<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Networking on Luis Logs</title>
    <link>https://luislogs.com/categories/networking/</link>
    <description>Recent content in Networking on Luis Logs</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Mon, 23 Mar 2026 18:40:30 +0900</lastBuildDate><atom:link href="https://luislogs.com/categories/networking/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Upgrading our home internet to 10 Gbps</title>
      <link>https://luislogs.com/posts/upgrading-our-home-internet-to-10-gbps/</link>
      <pubDate>Mon, 23 Mar 2026 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/upgrading-our-home-internet-to-10-gbps/</guid>
      <description>I have finally decided to move our internet subscription up from 1Gbps to 10Gbps. While 1G is already more than sufficient for home use, speed is not all there is. Beyond just raw speed, our old setup was held back by the overhead of PPPoE and the debatable limitation it brings when paired with a FreeBSD-based router OS like OPNsense. The new connection uses IPoE (IP over Ethernet) which doesn&amp;rsquo;t have the same hiccups the former is known to have.</description>
      <content:encoded><![CDATA[<p>I have finally decided to move our internet subscription up from 1Gbps to 10Gbps. While 1G is already more than sufficient for home use, speed is not all there is. Beyond just raw speed, our old setup was held back by the overhead of PPPoE and the debatable limitation it brings when paired with a FreeBSD-based router OS like OPNsense. The new connection uses IPoE (IP over Ethernet) which doesn&rsquo;t have the same hiccups the former is known to have.</p>
<p>Second, the old subscription only had IPv4. Don&rsquo;t get me wrong, IPv4 isn&rsquo;t a bad thing. In fact, a good majority of the internet still runs on IPv4. But recently, I&rsquo;ve gained interest in exploring the capabilities and other features that come with IPv6. More on this later, but the main trigger point for this is because IPv6 is already widely used in Japan. If I&rsquo;m not mistaken, IPv6 adoption has been enforced by the Japan Ministry of Communications for some time now.</p>
<p>Third, since the beginning of last year, I&rsquo;ve taken on a new role focused on optimizing customer experience performance, where speed is one of the main concerns. To better support this and overcome the limitations of my current toolset, having a speed test server (with multi-gigabit bandwidth) that I have full control of is a fundamental first step!</p>
<h2 id="hardware">Hardware</h2>
<p>Certain Lenovo Tiny PCs are popular machines for having a PCIe slot that can be fitted with 10G NICs, so that&rsquo;s what I went with. I was able to get a secondhand one with an Intel i5-8500T 6C CPU. This should be more than enough for my needs, even if I wanted to host other services on this machine. As for the NIC, I had the option of going with Mellanox or Intel ones. To be more specific, I was choosing between a Mellanox ConnectX-4 and an Intel X710-DA2. Mellanox seems to be more popular in terms of compatibility and stability, but it&rsquo;s also known to have elevated power consumption since it&rsquo;s not able to achieve higher C-states even when idle. The X710-DA2, on the other hand, was known to have compatibility issues, especially when using the OEM-branded ones. I went with Intel to have peace of mind knowing that I tried my best to save electricity costs (as if all the other machines in the homelab justify all the power they require!).</p>




	




































  	
	

	
		<script src="/shortcode-gallery/jquery-3.7.0.min.js"></script>
	
	
	
		<script src="/shortcode-gallery/lazy/jquery.lazy.min.js"></script>
	

	<script src="/shortcode-gallery/swipebox/js/jquery.swipebox.min.js"></script>
	<link rel="stylesheet" href="/shortcode-gallery/swipebox/css/swipebox.min.css">

	<script src="/shortcode-gallery/justified_gallery/jquery.justifiedGallery.min.js"></script>
	<link rel="stylesheet" href="/shortcode-gallery/justified_gallery/justifiedGallery.min.css"/>


<style>
	

	
</style>





<div id="gallery-0efe21febd1ec25b8e9ee6c88aecf11b-0-wrapper" class="gallery-wrapper">
<div id="gallery-0efe21febd1ec25b8e9ee6c88aecf11b-0" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/1_lenovo.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 6.765mm f/1.78<br/>6.764999865652793mm f/1.7799999713880652 1/25sec ISO 500"
						

						
					
					>
					<img			
						width="600" height="450"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AEmYDJP4Vk3PLVrDX7Z7WWwkE1osjBnUAHkeu4A4/GqUtnHPzbXkMmeitlGP4Gs7FXMlxgVDnBq9c2V3Bnzbd1A74yPzqiwGaYHZahCkjFZY1fHZh0rDksY42/dFoxkEgHIOO3Pauh1D/j5f/eNZE3ekV5lSCa6snzFKxT&#43;5uIH5UXl8t1C6NZRGRhhZMYYH1yKG6GoT/rBVXJe9z//Z"
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/1_lenovo_huc60cc3890e3e167b3b80c1e9ea5fec25_235863_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/7_nic1.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 2.22mm f/2.2<br/>2.220000028611935mm f/2.2 1/50sec ISO 160"
						

						
					
					>
					<img			
						width="600" height="336"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABIAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AK9xr8SsY7QedJ65wo/x/Cqerw66NGF3FzcTMFjiPylgeyL1Y06TT1XyXUIXj&#43;5sQcdMH/8AWKsR63PZiRjGJb4gKtxMSfl44Unpx2x&#43;fbGNJR1NZOTRyFm/iO8uka4klGx/I8qRcMSOqhePxP5&#43;/aJpyrY4ludshXLbRlfpU1vBdiH7TdSK8si4Py4IU87QeuMk59T1zVa6ucjjJGew6&#43;1auCe6JjcnsQPtXToVxS62q/2hEu0YYjIx15pLH/j6/Fadrf8AyEoPqP51Zb3AfLo7beMMQMem41kQ8gA/3v61r/8AMIf/AHz/AOhGsiHoP97&#43;tDBbn//Z"
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/7_nic1_hu71ac048810912ab87477b57d18108726_326997_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/8_nic2.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 2.22mm f/2.2<br/>2.220000028611935mm f/2.2 1/50sec ISO 200"
						

						
					
					>
					<img			
						width="600" height="385"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABUAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AK8NvOx2yK0bIdrLIhQqe4q3daalvD9oZNsJOA7LnOewz1qvpDi3vLoandP9oJ8wzzndux1ABPXv71k6pqk99eM8kzzIhITc3GO2Bxj8qiEI8raCrWcdCa7mDyf6xhATjAPP4jvSWWoXEMpFujOCcum7gj6euOOPTpVWOKa6jCi1lkDcFk/h98d/pV6XZbQG3ijKp1ldurAc8mpdzOnGbfMyDxCBBdwuoyZRz9Rj8&#43;DTrGKOZl3Rr98L09v/AK1N8U/8fFn/AMC/pUumfeX/AK6j&#43;tRQfuo6KkU6iubd6YtM06QwQjcELEk9cH/69cnPdOthuYs5kw7Ang98V1Wv/wDINn/64t/OuOuv&#43;Qcn/XMfyrZjkf/Z"
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/8_nic2_hu704a4dffdcd91781673407f0d3ec4de6_400167_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/9_riser.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 6.765mm f/1.78<br/>6.764999865652793mm f/1.7799999713880652 1/50sec ISO 100"
						

						
					
					>
					<img			
						width="600" height="354"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABMAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ADUVhgO2aUSnHzqgLHH06VzV1qTWjtDYLKEdQ00YXKsoOTjng8dsd66e80p7sfJbsD/eyR/OsHUNK1iwu0vgqXaRnJRT8wHce/8AnisacoJcppVjNu6LjBZYI5bTZLG6BtxyCM/Wq2&#43;dSCzMq9iOlQ6U8cN15PlMbeRTLbRvjlSfmjOe6n&#43;VaDlDMwCSCPaB&#43;9fdg&#43;wpypwUeZEUqs5PkluduwyCT2FZ9wAwfI6DitE/dP0rPm6SfSuU7DmNTjRthK8xXKshHG0lWz/IflWVbXEs8LPI2WzjoB/KtfUeh/67p/6C9Ylj/wAerfWun/l2cyX75n//2Q=="
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/lenovo_nic/9_riser_hu895237cd8829db7ecb56f54b8adc3baa_317968_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-0efe21febd1ec25b8e9ee6c88aecf11b-0");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<p>Unfortunately, I assumed the compatibility issue was something generic and could easily be fixed by cross-flashing the original Intel firmware. While this might have worked for others, this isn&rsquo;t the case when specifically using a Dell-branded X710 NIC with a Lenovo M920q Tiny PC. So, if anyone intends to follow this route, take note! I learned this the hard way because I purchased a Dell-branded one and went through the whole cross-flashing process only to find out that my machine will only boot up successfully if it&rsquo;s coming from an unplugged state. Yup, that means it will only boot up after unplugging and plugging the power cable. Anyway, I ended up purchasing an Intel-branded one and just flashed it with the latest firmware. For anyone interested, the articles I followed are also shared at the end of this post!</p>
<p>Lenovo M920q Tiny PCs require a PCIe riser for plugging in your cards. This can easily be bought for about ¥2000~3000 online. There are different part numbers in terms of the supported bus speed, so I had to ensure I got the one with P/N: 01AJ940, which supports x8.</p>
<p>As for the 10G switch, for the time being, I got a 4x2.5 + 2x10G switch from Horaco (AliExpress). I already have an 8x2.5G switch from the same brand and it&rsquo;s been rock stable. There was no really good reason for me to try out another brand. If there was one thing where you have to manage your risk, it&rsquo;s when purchasing networking equipment from AliExpress!</p>




	





































<style>
	

	
</style>





<div id="gallery-0efe21febd1ec25b8e9ee6c88aecf11b-1-wrapper" class="gallery-wrapper">
<div id="gallery-0efe21febd1ec25b8e9ee6c88aecf11b-1" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/network/2_horaco.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 2.22mm f/2.2<br/>2.220000028611935mm f/2.2 1/50sec ISO 500"
						

						
					
					>
					<img			
						width="600" height="311"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABEAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AKekaDpmkRQJepCdQt2YtNknqeB6HtW&#43;t7p6jm6j/Osi/GmatkNNtDYykqZ/qKiHhTS5FDvcQpvLHcYsDLcN/FWUZKxUou5v/wBo6cP&#43;XyHnsWqimj6dqQ&#43;y6PNbQ3KKzwlP4G9ePwrBufBlrPJui1aDYi&#43;WuMqAPzrf8OWWm&#43;HY8JqEbz95PMH5cmnJpoIxaZzEv3zVLUP9XB/13j/9Cq7L981S1D/Vwf8AXeP/ANCrlW50MnP3qsWX/H1F/vCq5&#43;9Viy/4&#43;ov94Uo7oGf/2Q=="
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/network/2_horaco_huda0d695b44ae1bd295d76d07d7427684_167972_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/network/3_sfp.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 6.765mm f/1.78<br/>6.764999865652793mm f/1.7799999713880652 1/100sec ISO 80"
						

						
					
					>
					<img			
						width="600" height="386"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABUAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ALhkEchkc4jDjcfbjNXZ1mhmMdrYIwwCJpXyDzz8vtVAr5ti6yEEMGxx6nikfT7nYsmo6m8gYZEMJwW9u2f881zU15G02advdyQM6X13bhGQgQQrgj3A6&#43;vrVQSB0RlYsCwIY9waWygvYmT7Bpkdva5BkkkOWde/IPp9R70sxgLsbaRHRGBOw8Lg8itKkXZMiDK0mfsYGf8Aln/Sq0WoCLQ476aBZntSVQE44HHXtxVqT/j0H&#43;5/Ssh/&#43;RRn/wB9v51NLdlVCWfWNR11/LuLkxwkgeTEMLj39fxrVisUs7F1Rs/KSePaud0r/Wr9RXWT/wDHo/8AuH&#43;VOTbeoopJaH//2Q=="
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/network/3_sfp_hu814eb0653470a35e31f2734fad4d4ec1_223230_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/network/4_dac.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 6.765mm f/1.78<br/>6.764999865652793mm f/1.7799999713880652 1/50sec ISO 100"
						

						
					
					>
					<img			
						width="600" height="450"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ANG81gwqmQoVnAODzjvVu30mxtYIp9S1Bo5JWL4knCrz/CPUCuV8TyNDZPGoViysSwGSBWp4cvTZWIRXnaFlUonDhRjnGSMde1S0os0d7GheQxwyg6fNHeryTHHdDzB9F7/zpq6ovloUiKsmQwfOR/I1qx6tashkUyIxByJGHA&#43;grmtP83U7i4v55RiZl2DqQgyB/LNLR77CQmqxQTeZGsagMhB2jrmsHT76&#43;0JTYtZSXlvtPlTRj5l9Af0reuf9a/0/rVI9V&#43;orCMu5bRUDahqkqj7PNaW&#43;7JZ&#43;rc/hjiumtBshSBpNxRQoJOSQOmaqx/8AHmPr/hU0H/H0v0H9K0b0I6n/2Q=="
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/network/4_dac_hu685d8aca29d5fc1d840947359a322285_285071_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-0efe21febd1ec25b8e9ee6c88aecf11b-1");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<p>10G SFP+ to copper transceivers are known to run hot. And because I keep my networking equipment in an unventilated closet, I had to shed an extra couple of bucks for the premium ones—the version that supports up to 80m of copper. For the transceivers, I got them from a brand called ZYOPM.</p>
<p>Managing the temperature inside an enclosed space is a priority, so I had to make sure the temps are at a minimum whenever possible. For the upstream connection of my switch to the router, I used a DAC cable. I&rsquo;ve never used one before and actually thought of using optical transceivers in the beginning.</p>




	





































<style>
	

	
</style>





<div id="gallery-0efe21febd1ec25b8e9ee6c88aecf11b-2-wrapper" class="gallery-wrapper">
<div id="gallery-0efe21febd1ec25b8e9ee6c88aecf11b-2" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/ap/5_tplink.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 6.765mm f/1.78<br/>6.764999865652793mm f/1.7799999713880652 1/100sec ISO 64"
						

						
					
					>
					<img			
						width="600" height="453"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AI9HhivbhS0aqicsT0roP7Ol126k8ry0t4hs82RMkHvgcc0y204WGjB3J8x&#43;SAAQSRwDnj/J/DR8O30ENubOV1jcMSu44DA/1qIQ5I2LqS55XKNx4GUxk21/ukA&#43;7ImFP5HiuQuoZbGdobmMRTKxUrux&#43;VeryzxW8ZklkWNB3Y4FeV&#43;LrxdT8RxPECIySV46hRjNTJLlbaKg3zJXKraf4is2Y2Erywg/IvmZIH0PFV28Qa7ZHbqFlvA6s8RU/mOP0rtLXtXPeLv9S1CbQ2kynF4wsXIE1rImePkIYD&#43;VVLi&#43;hvtXE1nPhUi4ypHJPTB&#43;lcxH3&#43;taGl/8fL/7gonJtNBCKUkz/9k="
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/ap/5_tplink_hu1052ddbb5c4b39337bd4edbccd50c8c0_245108_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/upgrading-our-home-internet-to-10-gbps/ap/6_injector.jpg" 
					class="galleryImg"
					
						

						
							data-description="iPhone 15 Pro Max + iPhone 15 Pro Max back triple camera 2.22mm f/2.2<br/>2.220000028611935mm f/2.2 1/100sec ISO 250"
						

						
					
					>
					<img			
						width="600" height="383"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABQAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AE8P2QvJzM8OyKI8kH7zeldBfaja2KxC7lLM&#43;Qq7AeBWRa&#43;I7Cwijtpre4hAH3gAyt6n1q5Lf6Fq0IimvYiOxfMbL9CQK0oSpQhZSVzixKrTq80ovl8jOv8AxLpUTYOnLIO5O0Gob3&#43;y7zQJtUsUKhXC42bWU5Ge&#43;D1rVs/C&#43;hgb40F1/tNJuH6cVLrVpHD4fuIraJIlG0hVUAZ3CtJ0&#43;aDk7GcKyjUjGF90VLKwtryARXEYkTrg9qdqfhXTYYN8QlQ&#43;z5/nU&#43;k/dFaWr/8AHp&#43;FcTimtUexd3PLJpZILtkjdhtzg55qSbW9SQQ2/wBrleKU4ZXYsMfjUN7/AMf8v1NVrn/X2v8AvmuPapZGrScdT//Z"
							
							class="lazy"
							data-src="/posts/upgrading-our-home-internet-to-10-gbps/ap/6_injector_hudadc7a1cc8e69714db852c4d3a521dca_241276_600x600_fit_q100_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-0efe21febd1ec25b8e9ee6c88aecf11b-2");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<p>On to the Wireless AP, I also upgraded from my not-so-old TP-Link EAP610 to an EAP773. The former only supported Wi-Fi 6 over 2.4/5 GHz bands with 1G upstream. For &ldquo;future-proofing,&rdquo; at least for the next few years, and to make use of the upgraded upstream, I needed something which at least supported Wi-Fi 6E over 6 GHz.</p>
<p>I also had to get a PoE++ 90W injector since the new switch didn&rsquo;t support PoE+.</p>
<h2 id="software">Software</h2>
<p>There are mixed opinions on whether you should virtualize your router or not. But if you live somewhere where space is a luxury, then you already have the best reason to go with virtualization (but regardless of that, I just really like complicating things, lol). So of course, we go back to our good old friend, Proxmox. The last time I had to spin up a new Proxmox machine was about 2 years ago when I started using CEPH as my default backend storage. A lot of good things must have been added within these 2 years, but I just really needed an easily managed KVM host. No one can beat Proxmox on that.</p>
<p>As for the router itself, I made the big switch from OPNsense to OpenWRT. And I couldn&rsquo;t be happier. I&rsquo;ve had OPNsense for about 3 years now and while I didn&rsquo;t really complain about anything since it was more of a &ldquo;set and forget&rdquo; setup, whenever I had to modify something in the configuration, sometimes it just felt like I had to explore and familiarize myself again. With OpenWRT, the GUI just felt a bit more natural and warm to my eyes. Maybe it&rsquo;s because of fewer sections or tabs to go through, or, I don&rsquo;t know, configuration just seemed a little more straightforward this time compared to when I just started with the other.</p>
<p>But in fact, I don&rsquo;t think I would have bothered checking out OpenWRT if only OPNsense supported MAP-E connections used by my new ISP. There is a way to get it working with OPNsense, but it was more of a workaround than a natively supported feature.</p>
<h2 id="my-choice-of-isp">My choice of ISP</h2>
<p>The primary factor in choosing the ISP is the monthly cost. The switch to 10G wouldn&rsquo;t be justifiable if we had to pay 50% more than our old subscription. Second would be the option to have a fixed IPv4 address since I host some services for family and friends. Fortunately, I came across a post on Reddit suggesting <a href="https://enhikari.jp/">En Hikari</a>. En Hikari uses NTT FLET&rsquo;S HIKARI as the backbone provider, so you can be assured of the same quality of connectivity used by most ISPs. At the time of writing, the monthly cost is about JPY 4,917 (tax included) plus an additional JPY 770 for the optional fixed IPv4 address. That&rsquo;s a total of JPY 5,687, which comes out even cheaper than our current basic 1G subscription at JPY 5,720 (dynamic IPv4 address only).</p>
<h2 id="preparations">Preparations</h2>
<p>When I got the Intel X710 card, it only had v6.01 installed. I didn&rsquo;t find a way to upgrade directly from v6.01 to the latest one (v9.56 as of this writing) and had to go through it stepwise. The upgrade path in my case was from 6.01 &ndash;&gt; 8.6 &ndash;&gt; 9.0 &ndash;&gt; 9.10 &ndash;&gt; 9.56. All done under Debian (Proxmox).</p>
<p>My Intel card came with unlocked vendor support, so I didn&rsquo;t have to run the unlocker script. I guess this is only applicable to the OEM versions.</p>
<p>I actually ran into some errors initially that prevented the second Ethernet port from functioning. Honestly, I hit a wall and gave up on it for the night. Then, I&rsquo;m not sure how, but it just got resolved the following morning after a restart.</p>
<p>After a few more rounds of restarts and going through kernel dmesg logs, I finally decided to go with a fresh install of OpenWRT. For some reason, I couldn&rsquo;t figure out how to create the VLAN interfaces from the GUI. I ended up with a successful attempt when I tried to do it from the text file configuration. To those who are in the same boat, below is a sample <code>/etc/config/network</code> for configuring VLANs.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">config interface &#39;loopback&#39;
</span></span><span class="line"><span class="cl">	option device &#39;lo&#39;
</span></span><span class="line"><span class="cl">	option proto &#39;static&#39;
</span></span><span class="line"><span class="cl">	option ipaddr &#39;127.0.0.1&#39;
</span></span><span class="line"><span class="cl">	option netmask &#39;255.0.0.0&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config globals &#39;globals&#39;
</span></span><span class="line"><span class="cl">	option ula_prefix &#39;fd00:7808:88c3::/48&#39;
</span></span><span class="line"><span class="cl">	option packet_steering &#39;1&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config device
</span></span><span class="line"><span class="cl">	option name &#39;br-lan&#39;
</span></span><span class="line"><span class="cl">	option type &#39;bridge&#39;
</span></span><span class="line"><span class="cl">	list ports &#39;eth0&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config interface &#39;lan&#39;
</span></span><span class="line"><span class="cl">	option device &#39;br-lan.1&#39;
</span></span><span class="line"><span class="cl">	option proto &#39;static&#39;
</span></span><span class="line"><span class="cl">	option ipaddr &#39;192.168.0.1&#39;
</span></span><span class="line"><span class="cl">	option netmask &#39;255.255.255.0&#39;
</span></span><span class="line"><span class="cl">	option ip6assign &#39;64&#39;
</span></span><span class="line"><span class="cl">	list dns &#39;192.168.0.1&#39;
</span></span><span class="line"><span class="cl">	option ip6hint &#39;00&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config interface &#39;wan&#39;
</span></span><span class="line"><span class="cl">	option device &#39;eth1&#39;
</span></span><span class="line"><span class="cl">	option proto &#39;dhcp&#39;
</span></span><span class="line"><span class="cl">	option keepalive &#39;5 10&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config interface &#39;wan6&#39;
</span></span><span class="line"><span class="cl">	option device &#39;eth1&#39;
</span></span><span class="line"><span class="cl">	option proto &#39;dhcpv6&#39;
</span></span><span class="line"><span class="cl">	option reqaddress &#39;try&#39;
</span></span><span class="line"><span class="cl">	option reqprefix &#39;auto&#39;
</span></span><span class="line"><span class="cl">	option norelease &#39;1&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config bridge-vlan
</span></span><span class="line"><span class="cl">	option device &#39;br-lan&#39;
</span></span><span class="line"><span class="cl">	option vlan &#39;1&#39;
</span></span><span class="line"><span class="cl">	list ports &#39;eth0&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config bridge-vlan
</span></span><span class="line"><span class="cl">	option device &#39;br-lan&#39;
</span></span><span class="line"><span class="cl">	option vlan &#39;10&#39;
</span></span><span class="line"><span class="cl">	list ports &#39;eth0:t&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config bridge-vlan
</span></span><span class="line"><span class="cl">	option device &#39;br-lan&#39;
</span></span><span class="line"><span class="cl">	option vlan &#39;20&#39;
</span></span><span class="line"><span class="cl">	list ports &#39;eth0:t&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config interface &#39;vlan10&#39;
</span></span><span class="line"><span class="cl">	option proto &#39;static&#39;
</span></span><span class="line"><span class="cl">	option device &#39;br-lan.10&#39;
</span></span><span class="line"><span class="cl">	option ipaddr &#39;192.168.10.1&#39;
</span></span><span class="line"><span class="cl">	option netmask &#39;255.255.255.0&#39;
</span></span><span class="line"><span class="cl">	list dns &#39;192.168.10.0.1&#39;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">config interface &#39;vlan20&#39;
</span></span><span class="line"><span class="cl">	option proto &#39;static&#39;
</span></span><span class="line"><span class="cl">	option device &#39;br-lan.20&#39;
</span></span><span class="line"><span class="cl">	option ipaddr &#39;192.168.20.1&#39;
</span></span><span class="line"><span class="cl">	option netmask &#39;255.255.255.0&#39;
</span></span><span class="line"><span class="cl">	list dns &#39;192.168.20.0.1&#39;
</span></span></code></pre></div><p><code>/etc/init.d/network restart</code> to apply the config.</p>
<p>For now, I just wanted a stable internet connection and didn&rsquo;t even bother to think about having SR-IOV, so it&rsquo;s been decided to just make use of the existing Proxmox Linux bridges for both the WAN and LAN interface.</p>
<h2 id="en-hikari-configuration-on-openwrt">En Hikari configuration on OpenWRT</h2>
<p><strong>References:</strong>
<a href="https://note.com/arunya/n/n7d81e0de9db7">https://note.com/arunya/n/n7d81e0de9db7</a>
<a href="https://www.ficusonline.com/ja/posts/openwrt-v6-plus-map-e">https://www.ficusonline.com/ja/posts/openwrt-v6-plus-map-e</a></p>
<p>I found these two articles that provide step-by-step instructions to get En Hikari working with v6 plus and the fixed IPv4. The initial steps to have DHCPv6 working are in the first one. In my case, I installed the required packages first:</p>
<ul>
<li>luci-proto-ipv6</li>
<li>map</li>
<li>ds-lite</li>
<li>ip-full</li>
</ul>
<p>As I know Hikari Cross utilizes MAP-E. I am not sure if <code>ds-lite</code> is really required, but I just installed it anyway.</p>
<p>I created a new WAN interface, named it &lsquo;wan6&rsquo;, and set the protocol to <code>DHCPv6 client</code>. Under DHCP Server &gt; IPv6 Settings, the RA-Service, DHCPv6 Service, and NDP Proxy were all set to disabled. After a few seconds, I was assigned an IPv6 /56 subnet.</p>
<p>
    <img src="/posts/upgrading-our-home-internet-to-10-gbps/wan6_dhcp.png" alt="wan6 DHCP settings">
  </p>
<p>For the clients to connect over IPv6, I had to enable IPv6 under <strong>Interfaces &gt; LAN &gt; Advanced Settings</strong>. IPv6 assignment length was set to <code>64</code> and hint to <code>00</code> so my LAN gets assigned the first smaller subnet of the /56 block.</p>
<p>Under <strong>LAN &gt; DHCP Server &gt; IPv6 Settings</strong>, RA-Service and DHCPv6 Service should be set to <code>server</code> and NDP Proxy to <code>relay</code>. Under IPv6 RA Settings, I made sure SLAAC was enabled. The rest were set to default. After applying the changes, my devices started having an IPv6 address, the majority by SLAAC and a very few through DHCPv6.</p>
<p>For the IPv4 configuration, I just followed the article. Though I am still sharing my snaps here for future reference:</p>
<p>Info that was provided by the ISP:</p>
<ul>
<li>V4アドレス</li>
<li>インターフェスID</li>
<li>BRアドレス</li>
<li>ユーサID</li>
<li>パスワード</li>
</ul>
<p>
    <img src="/posts/upgrading-our-home-internet-to-10-gbps/map-e_1.png" alt="MAP-E configuration">
  </p>
<p>
    <img src="/posts/upgrading-our-home-internet-to-10-gbps/map-e_2.png" alt="MAP-E configuration">
  </p>
<p>
    <img src="/posts/upgrading-our-home-internet-to-10-gbps/map-e_3.png" alt="MAP-E configuration">
  </p>
<h2 id="quick-speed-test">Quick speed test</h2>
<p>I don&rsquo;t have any other equipment (yet, lol) that supports 10G traffic, so I spun up an LXC container on the same PVE hosting OpenWRT and ran a simple iPerf test from there. I selected one of the JP servers from <a href="https://github.com/R0GGER/public-iperf3-servers">this list</a> maintained by <a href="https://github.com/R0GGER">@R0GGER</a> (Big thanks to him!).</p>
<p>The result, DL and UL speed respectively:</p>
<p>The result:</p>
<p><strong>DL SPEED</strong>

    <img src="/posts/upgrading-our-home-internet-to-10-gbps/10_dlspeed.png" alt="DL Speed">
  </p>
<p><strong>UL SPEED</strong>

    <img src="/posts/upgrading-our-home-internet-to-10-gbps/11_ulspeed.png" alt="UL Speed">
  </p>
<p>I may not be getting the full 10G bandwidth, but I&rsquo;m certainly getting ~5x the speed compared to my previous connection for the same price.</p>
<h2 id="whats-next">What&rsquo;s next</h2>
<p>In addition to the benefits a multi-gigabit upstream brings, being assigned an IPv6 subnet from my ISP will allow me to host multiple services from within my local network since the hosts will now have publicly routable addresses. This means a few things:</p>
<ol>
<li>No need to keep track and configure ports for port-forwarding to different VMs or containers.</li>
<li>Multiple services can be hosted on the same port.</li>
<li>I can create a DMZ network to completely expose hosts to the public internet.</li>
<li>P2P connectivity can be established without the requirement of NAT-ing.</li>
</ol>
<h2 id="references">References</h2>
<ul>
<li><a href="https://gist.github.com/mietzen/736583d37a1d370273c0775aaaa57aa5">Cross-flashing X710 NICs</a></li>
<li><a href="https://github.com/bibigon812/xl710-unlocker/tree/master#">Disabling vendor-lock of X710 NICs</a></li>
<li><a href="https://www.moduletek.com/en/application_notes/an_00115.html">Explanation of above</a></li>
<li><a href="https://gist.github.com/subrezon/b9aa2014343f934fbf69e579ecfc8da8">OpenWRT on Proxmox</a></li>
<li><a href="https://note.com/arunya/n/n7d81e0de9db7">OpenWRT configuration for En Hikari with v6 plus and Fixed IP</a></li>
<li><a href="https://www.intel.com/content/www/us/en/download/18635/non-volatile-memory-nvm-update-utility-for-intel-ethernet-adapters-700-series-linux.html">Intel X710 drivers</a></li>
</ul>
]]></content:encoded>
    </item>
    
    <item>
      <title>Secure HTTP access to services with Traefik, Cert-manager and Cloudflare</title>
      <link>https://luislogs.com/posts/secure-http-access-to-services-with-traefik-cert-manager-and-cloudflare/</link>
      <pubDate>Sun, 26 Nov 2023 09:20:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/secure-http-access-to-services-with-traefik-cert-manager-and-cloudflare/</guid>
      <description>Before I started working on spinning up my 3-node K3s cluster, I was under the impression that Traefik would be one of the easiest to migrate from my docker setup since it already had some kind of native integration with Kubernetes in terms of available custom resources. Unfortunately this wasn&amp;rsquo;t the case as with my personal experience. Reading through the custom values yaml file and referring to the available documentation to figure out how the docker configuration compares to when deploying in K8s wasn&amp;rsquo;t as straightforward as I expected.</description>
      <content:encoded><![CDATA[<p>Before I started working on spinning up my 3-node K3s cluster, I was under the impression that Traefik would be one of the easiest to migrate from my docker setup since it already had some kind of native integration with Kubernetes in terms of available custom resources. Unfortunately this wasn&rsquo;t the case as with my personal experience. Reading through the custom values yaml file and referring to the available documentation to figure out how the docker configuration compares to when deploying in K8s wasn&rsquo;t as straightforward as I expected. The part where I took time the most was when I was working on setting up automatic TLS certificate provisioning for the backend services I was running.</p>
<p>I got everything working eventually after multiple iterations of trial and error, and upgrading my traefik helm release countless times. And after finding this <a href="https://traefik.io/blog/secure-web-applications-with-traefik-proxy-cert-manager-and-lets-encrypt/">Traefik blog post</a> where they explain how it all actually works and can be configured. At this point I&rsquo;ve migrated all of my docker applications into my k8s cluster, and reading through the Traefik documentation again, it just makes a lot more sense now.</p>
<p>I guess the most important bit of the documentation is the part where they mentioned the requirement of using Cert-manager when using Traefik Proxy in Kubernetes.
Quoting from the documentation:</p>
<blockquote>
<p><strong>LetsEncrypt Support with the Ingress Provider</strong>
By design, Traefik is a stateless application, meaning that it only derives its configuration from the environment it runs in, without additional configuration. For this reason, users can run multiple instances of Traefik at the same time to achieve HA, as is a common pattern in the kubernetes ecosystem.
When using a single instance of Traefik Proxy with Let&rsquo;s Encrypt, you should encounter no issues. However, this could be a single point of failure. Unfortunately, it is not possible to run multiple instances of Traefik 2.0 with Let&rsquo;s Encrypt enabled, because there is no way to ensure that the correct instance of Traefik receives the challenge request, and subsequent responses. Previous versions of Traefik used a KV store to attempt to achieve this, but due to sub-optimal performance that feature was dropped in 2.0.
If you need Let&rsquo;s Encrypt with high availability in a Kubernetes environment, we recommend using Traefik Enterprise which includes distributed Let&rsquo;s Encrypt as a supported feature.
If you want to keep using Traefik Proxy, LetsEncrypt HA can be achieved by using a Certificate Controller such as Cert-Manager. When using Cert-Manager to manage certificates, it creates secrets in your namespaces that can be referenced as TLS secrets in your ingress objects.</p>
</blockquote>
<p>Since we are working in K8s, almost everything you can think of can be abstracted. For this instance, the TLS configuration is abstracted from the helm custom values yaml file and instead can be pegged to an Ingress resource when using Cert-manager.</p>
<p>To summarize in a few lines:</p>
<ul>
<li>Install Traefik so it can act your Ingress controller.</li>
<li>Install Cert-manager so it can monitor your Ingress resources, and based on the TLS configuration and with some annotations, it will automatically initiate the DNS challenge, create the TLS certificates sand save them as a secret in the application namespace.</li>
<li>Create Ingress resources to access your backend servcies while at the same time terminate HTTPS traffic (with Traefik).</li>
</ul>
<p>
    <img src="/posts/secure-http-access-to-services-with-traefik-cert-manager-and-cloudflare/traefik_1.png" alt="Traefik and Cert-manager flow">
  </p>
<p>Do note that while Traefik is an ingress controller and comes with its own IngressRoute CRD, it cannot be used together with Cert-manager at the moment. In this case we have to use the default Kubernetes Ingress resource.</p>
<p>In this post I will show how I configured Traefik and Cert-manager (patterned to the Traefik blog post!) to be used with Cloudflare. I will also show how you can have another layer of security by having multiple entry points and explicitly defining one during the ingress configuration. Though before proceeding, do note that I assume you already have an idea how to configure dynamic DNS and port-forwarding on Cloudflare and on your router.</p>
<h2 id="traefik">Traefik</h2>
<p>Recently I&rsquo;ve started using ArgoCD for managing all my applications including those that are installed via helm charts. For now we will install Traefik using helm.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">helm repo add traefik https://traefik.github.io/charts <span class="c1"># Add the Traefik repository</span>
</span></span><span class="line"><span class="cl">helm repo update <span class="c1"># Update the repositories</span>
</span></span><span class="line"><span class="cl">helm show values traefik/traefik &gt; values.yaml <span class="c1"># Download the custom values yaml</span>
</span></span></code></pre></div><p>I would recommend you to browse through the custom values yaml file to get familiarized with the available configuration and other features of Traefik. If you want to get started quickly then you can follow the below yaml configuration:</p>
<p><em>values.yaml</em></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">deployment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Deployment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">replicas</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">terminationGracePeriodSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">60</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">minReadySeconds</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">ingressRoute</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">dashboard</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">matchRule</span><span class="p">:</span><span class="w"> </span><span class="l">Host(`traefik.yownowndomain.com`) &amp;&amp; PathPrefix(`/dashboard`) || Host(`traefik.yownowndomain.com`) &amp;&amp; PathPrefix(`/api`)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">entryPoints</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;traefik&#34;</span><span class="p">,</span><span class="s2">&#34;websecure&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">additionalArguments</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s2">&#34;--serversTransport.insecureSkipVerify=true&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s2">&#34;--providers.kubernetesingress.ingressendpoint.publishedservice=traefik/traefik&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">traefik</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">9000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">9000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">web</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">redirectTo</span><span class="p">:</span><span class="w"> </span><span class="l">websecure</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">webext</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">8080</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">redirectTo</span><span class="p">:</span><span class="w"> </span><span class="l">websecureexternal</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">websecure</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">http3</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">options</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">certResolver</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">middlewares</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">default-default@kubernetescrd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">websecureext</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">8443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">8443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">http3</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">options</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">certResolver</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">middlewares</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">default-default@kubernetescrd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">metrics</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">9100</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">9100</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">dnsovertls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">8853</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">expose</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedPort</span><span class="p">:</span><span class="w"> </span><span class="m">853</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">middlewares</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">default-default@kubernetescrd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">tlsOptions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">minVersion</span><span class="p">:</span><span class="w"> </span><span class="l">VersionTLS12</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">cipherSuites</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="l">TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">service</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">single</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">LoadBalancer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">io.cilium/lb-ipam-ips</span><span class="p">:</span><span class="w"> </span><span class="m">10.80.0.2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedExternal</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;yes&#34;</span><span class="w">
</span></span></span></code></pre></div><p>In my custom yaml file notice that I have four different entryPoints defined. I configured it like this to have separate incoming streams between my internal-only applications against the internet-exposed ones. Having a common entryPoint for both internal and externally exposed applications is a security flaw since hackers might still be able to access your internal-only apps if they guessed the sub-domain and locally configured CNAME forwarding (they don&rsquo;t need access to your DNS configuration).</p>
<p>Once your custom values yaml file is ready. Hit up the helm install command and proceed to the next step to create a Middleware resource.</p>
<p><em>default-middleware.yaml</em></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">traefik.io/v1alpha1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Middleware</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">traefik</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">headers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">customResponseHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">X-Robots-Tag</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;none,noarchive,nosnippet,notranslate,noimageindex&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">X-Forwarded-Proto</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">customRequestHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">X-Forwarded-Proto</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">sslProxyHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">X-Forwarded-Proto</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">referrerPolicy</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;same-origin&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">hostsProxyHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="s2">&#34;X-Forwarded-Host&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">contentTypeNosniff</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">browserXssFilter</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">forceSTSHeader</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">stsIncludeSubdomains</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">stsSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">63072000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">stsPreload</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span></code></pre></div><p><code>helm install traefik/traefik -f values.yaml</code></p>
<p><code>kubectl apply -f default-middleware.yaml</code></p>
<p>Now that you have Traefik up and running, expose the <code>webext</code> and <code>websecureext</code> entryPoints on your router. Simply port-forward 80 to 8080, and 443 to 8443.</p>
<h2 id="cloudflare">Cloudflare</h2>
<p>Going to Cloudflare, you have to configure an access token to be used later on when configuring Cert-manager. Login to your Cloudflare account. Navigate to My Profile &gt; API Tokens &gt; Create Token.</p>
<p>Under Permissions, set Zone - DNS - Edit</p>
<p>Under Zone Resources, set Include - Specific zone - &ldquo;yourowndomain.com&rdquo;</p>
<p>E.g.

    <img src="/posts/secure-http-access-to-services-with-traefik-cert-manager-and-cloudflare/cf_1.png" alt="Cloudflare Access Token">
  </p>
<p>Create and save your token somewhere safe.</p>
<h2 id="cert-manager">Cert-manager</h2>
<p>Cert-manager can be installed using helm. Quoting from the official documentation, Cert-Manager together with the CRDs can be installed with the following commands:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">helm repo add jetstack https://charts.jetstack.io
</span></span><span class="line"><span class="cl">helm repo update
</span></span><span class="line"><span class="cl">helm install <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  cert-manager jetstack/cert-manager <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --namespace cert-manager <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --create-namespace <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --version v1.13.2 <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>  --set <span class="nv">installCRDs</span><span class="o">=</span><span class="nb">true</span>
</span></span></code></pre></div><p>After installation, it&rsquo;s time to configure cert-manager for use with Cloudflare. You simply just have to create a secret containing your cloudflare email and API token:</p>
<p><em>cloudflare-api-token-secret.yaml</em></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Secret</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">cloudflare-api-token</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l">cert-manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">Opaque</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">stringData</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">email</span><span class="p">:</span><span class="w"> </span><span class="l">example@domain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">apiToken</span><span class="p">:</span><span class="w"> </span><span class="l">AbcD321eFg456_</span><span class="w">
</span></span></span></code></pre></div><p>Next is to create a ClusterIssuer resource. This is one of the CRDs that will come with cert-manager. Here you have to specify your email to be used with Let&rsquo;s Encrypt as well as the secret you created in the previous step.</p>
<p><em>clusterissuer.yaml</em></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">cert-manager.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">ClusterIssuer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">letsencrypt-cluster-issuer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l">cert-manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">acme</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">email</span><span class="p">:</span><span class="w"> </span><span class="l">example@domain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Prod</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="l">https://acme-v02.api.letsencrypt.org/directory</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># We use the staging server here for testing to avoid hitting</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">#    server: https://acme-staging-v02.api.letsencrypt.org/directory</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">privateKeySecretRef</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># if not existing, it will register a new account and stores it</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">letsencrypt-acc-key</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">solvers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">dns01</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="c"># The ingressClass used to create the necessary ingress routes</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">cloudflare</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">email</span><span class="p">:</span><span class="w"> </span><span class="l">example@domain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">apiTokenSecretRef</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">cloudflare-api-token</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">apiToken</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">selector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">dnsZones</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="s1">&#39;yourowndomain.com&#39;</span><span class="w">
</span></span></span></code></pre></div><p>If you are doing this the first time, I strongly suggest you first use the staging server of Let&rsquo;s Encrypt and ensure certificate issuance works fine. To switch to the porduction server all you have to do is just re-create the resource and point to the new URL. Do note in the example above, the resource is pointing to the production server.</p>
<h2 id="exposing-your-application">Exposing your application</h2>
<p>To test this we create a simple nginx deployment that is exposed within the cluster and an ingress resource.</p>
<p><em>nginx.yaml</em></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apps/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Deployment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx-deployment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">selector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">matchLabels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">replicas</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">template</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">nginx:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">containerPort</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Service</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">selector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;http&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">targetPort</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">ClusterIP</span><span class="w">
</span></span></span></code></pre></div><p>When creating the ingress manifest, you have to ensure that you have the annotation: <code>cert-manager.io/cluster-issuer: &quot;letsencrypt-cluster-issuer&quot;</code>.</p>
<p>Apart from this if you want your application to be accessed from a specific traefik entryPoint, then you need to explicitly mention this as another annotation. By default the ingress will be allowed from any entryPoint if you don&rsquo;t specify this. In the below example manifest, I am keeping this annotation commented out so I can access my Nginx app from both internal and external entryPoints.</p>
<p><em>nginx-ingress.yaml</em></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">networking.k8s.io/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Ingress</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">annotations</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">cert-manager.io/cluster-issuer</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;letsencrypt-cluster-issuer&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># traefik.ingress.kubernetes.io/router.entrypoints: websecureext</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">nginx.yownowndomain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">secretName</span><span class="p">:</span><span class="w"> </span><span class="l">tls-nginx-ingress</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">rules</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">host</span><span class="p">:</span><span class="w"> </span><span class="l">nginx.yownowndomain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">http</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">paths</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">pathType</span><span class="p">:</span><span class="w"> </span><span class="l">Prefix</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">backend</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">service</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">port</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">number</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span></code></pre></div><p>Once you apply these manifests, simply do a <code>kubectl get certificate</code>. This will show that a new certificate and secret resource got automatically created.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">kubectl get certificate
</span></span><span class="line"><span class="cl">NAME                READY   SECRET              AGE
</span></span><span class="line"><span class="cl">tls-nginx-ingress   False   tls-nginx-ingress   61s
</span></span></code></pre></div><p>Wait for a few minutes. You should see that cerficicate ready status should be set to True.</p>
<p>You can also describe this certificate to see the events.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Events:
</span></span><span class="line"><span class="cl">  Type    Reason     Age   From                                       Message
</span></span><span class="line"><span class="cl">  ----    ------     ----  ----                                       -------
</span></span><span class="line"><span class="cl">  Normal  Issuing    91s   cert-manager-certificates-trigger          Issuing certificate as Secret does not exist
</span></span><span class="line"><span class="cl">  Normal  Generated  90s   cert-manager-certificates-key-manager      Stored new private key in temporary Secret resource &#34;tls-nginx-ingress-2mvlp&#34;
</span></span><span class="line"><span class="cl">  Normal  Requested  90s   cert-manager-certificates-request-manager  Created new CertificateRequest resource &#34;tls-nginx-ingress-1&#34;
</span></span><span class="line"><span class="cl">  Normal  Issuing    11s   cert-manager-certificates-issuing          The certificate has been successfully issued
</span></span></code></pre></div><p>To expose this on the internet, you will have to go back to Cloudflare and configure a CNAME forwarding to the sub-domain that points to your router&rsquo;s external IP, given that you have already configured dynamic DNS.</p>
<p>You can also test this by configuring a CNAME entry on your local network&rsquo;s DNS.</p>
<p>Once you ge this working you should be able to see a valid certificate when you access your nginx page.</p>
<p>
    <img src="/posts/secure-http-access-to-services-with-traefik-cert-manager-and-cloudflare/nginx.png" alt="Nginx TLS">
  </p>
<p>The certificate will have a validity of 3 months but you don&rsquo;t have to worry since Cert-manager will renew this automatically.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>State of the Network — the first 120 days</title>
      <link>https://luislogs.com/posts/state-of-the-network-the-first-120-days/</link>
      <pubDate>Sun, 16 Jul 2023 00:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/state-of-the-network-the-first-120-days/</guid>
      <description>The past months have been crazy since the induction of my homelab. There have been so much reading here and there and a bulk of what used to be my idle time has since been allotted to technical research and self-development. My writing has not been able to keep up either because there have been a lot of changes and modifications I’ve been doing from the get-go.
The network just reached the fourth month mark and it’s already about to undergo a somewhat major re-design.</description>
      <content:encoded><![CDATA[<p>The past months have been crazy since the induction of my homelab. There have been so much reading here and there and a bulk of what used to be my idle time has since been allotted to technical research and self-development. My writing has not been able to keep up either because there have been a lot of changes and modifications I’ve been doing from the get-go.</p>
<p>The network just reached the fourth month mark and it’s already about to undergo a somewhat major re-design. But just before going to the next chapter of the journey, I want to take this time to log the current state of the existing infrastructure and services. Don&rsquo;t get me wrong — I don&rsquo;t run a full-fledged data center, nor do I even have a server rack setup. I only have photos and videos as critical files and I only have two users at home including myself (lol). It&rsquo;s called a homelab for a reason. Though it would still be fun to document the progress be it big or small and know how far I&rsquo;ve come along the way.</p>
<h2 id="homelab-networking-and-hardware">Homelab Networking and Hardware</h2>
<p>On high level, below is the current diagram of existing services, subnets, VLANs, and devices.</p>
<p>



	




































  	
	

	
		<script src="/shortcode-gallery/jquery-3.7.0.min.js"></script>
	
	
	
		<script src="/shortcode-gallery/lazy/jquery.lazy.min.js"></script>
	

	<script src="/shortcode-gallery/swipebox/js/jquery.swipebox.min.js"></script>
	<link rel="stylesheet" href="/shortcode-gallery/swipebox/css/swipebox.min.css">

	<script src="/shortcode-gallery/justified_gallery/jquery.justifiedGallery.min.js"></script>
	<link rel="stylesheet" href="/shortcode-gallery/justified_gallery/justifiedGallery.min.css"/>


<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-0-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-0" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/diagram/diagram.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="388"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABUAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AO/utevIdae2VkESyhTkZOOK1Tr&#43;lg4N0v8A3yax73RLmXWmnyux5Aw&#43;YZwPqatnwpAf&#43;XqUf5P&#43;NePTljYym1G&#43;ul/02O&#43;aw7Ubu2nQvLr&#43;mOwVboEk4A2n/Crn2iP3/I1jx&#43;F4Y5VkF3KSrA4wK3a78PKvJP20UvT/AIdnNVVJW9m7kLAmVY3wVOT3HSpqib/j5T/dNS10mIUUUUAf/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/diagram/diagram_hub7bb2a9756cb13f6f6e108173f8af10e_121105_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-0");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<table>
<thead>
<tr>
<th>VLAN</th>
<th>Traffic type</th>
<th>Services</th>
</tr>
</thead>
<tbody>
<tr>
<td>Untagged</td>
<td>Local</td>
<td>Local devices, DNS</td>
</tr>
<tr>
<td>10</td>
<td>Docker</td>
<td>Traefik, UptimeKuma, InfluxDB, Grafana, Code-server, Firefox, Guacamole, JDownloader, Jellyfin, Krusader, Wiki.js</td>
</tr>
<tr>
<td>20</td>
<td>VM</td>
<td>Setagaya Workstation (PopOS), GNS3 server (Ubuntu 22.04), Voyager-staging (staging environment for remote server), Windows 10</td>
</tr>
<tr>
<td>30</td>
<td>LXC</td>
<td>Tailscale, Deluge</td>
</tr>
</tbody>
</table>
<p>Orange boxes signify the servers running a hypervisor — one Proxmox, and the other, Unraid. The Proxmox box is mainly running my network stack which includes OPNsense, a LXC container running Pihole as my DNS, and another one running tailscale for a machine-to-machine VPN with the remote peer acting as an exit node. While it might be possible to run tailscale from within OPNsense, I decided to configure it separately since I only have a simple use case of tunneling torrent traffic to a small thin client back home in Manila.</p>
<p>On the other hand, the box running Unraid primarily runs our NAS and a couple of docker containers and VMs. It&rsquo;s been very stable, running without any hiccup except for the time when all containers and VMs together with all the other devices were on a single subnet. This is what pushed me to segregate the traffic with VLANs. Speaking of, this is easily made possible by a cheap “smart” (you can say it’s managed) switch from TP-Link. I can’t stress enough how much I love this brand! I’ve been using their routers for more than a decade now and it has never failed me.</p>
<p>Back to the Unraid server, it had also undergone some few upgrades (the initial specs can be found in one of my first few posts <a href="https://luislogs.com/posts/new-nas-and-homelab-setup-using-unraid/">here</a>). First is the addition of a 500GB SSD as an un-mirrored cache drive to avoid wear and tear of the NVMe drives. This is also mainly used for non-critical data such as when storing movies, tv shows, and ISO files, etc.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-1-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-1" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/ssd/samsung_860_evo_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>9mm f/2.4 0.0303sec ISO 1000"
						

						
					
					>
					<img			
						width="600" height="452"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AKniV7W98SEyFg80fyKq5UKoxj/x01W03xFFFaxizj0&#43;1UpgRm2O8&#43;5IJyT1/Gtk6KLjV4tUZ3UrA4VOCCCZDz6f/WpBpdvPaR3DRfPICxwAMjJ9qvUjRmQ3iS6nOy80WKdH4ybUEAe5DGsOePQr68lQWs1m4fDHzPkySBnnnH0Irs7nQ7axiaVHTdnKgOD&#43;mOa88nYK2oEbjtlPyk8YEg/&#43;vQ79QVj0jStQtRo9q3mwDbAFl/fLlThjz7/NUP8Ab1pawxxRXVrII12jLDJH51ymm/8AILuvx/lWR2X/AHaYHaT&#43;JYpIzHIlsgfo&#43;4ZxmubbSZZ4ZihYJdPvD7TtUFgS270AFUbr7tv/ALn9a6y3/wCRah/69JP5Gna7E3ZH/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/ssd/samsung_860_evo_res_huf4f05a43168f222215b51547a553bbe1_223148_600x600_fit_q90_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-1");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>Second is the installation of a third party heat sink for the NVMe drives which brought down temperature levels by about 5-10C.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-2-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-2" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
					
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/nvme/20230408_204511_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>6.7mm f/1.8 1/100sec ISO 320"
						

						
					
					>
					<img			
						width="450" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAGAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ANrRZYpL1Z4IEjEEe1/MT5wuOBn3IB9Dg1xOtrHqGtTtHGyw3ThVl6hGJ647Z4/WumuBcPoMJa5VL&#43;VcTlH&#43;QZ52sBxwCATjqeODXG3Nld28wW4uLtCSeIZdgfnjB6U0imza1bw6umWYvLCa4dchprZXHz4/iBI/HHPesT&#43;0T/z43v8A30n/AMRT/tFwkf2jy7gtCyCLzJd6L13A5PccYHvUn/CQ3/8Az7Wn/fof4UwE0/xM8ey2uLYEBduCcn6j1rpDNaz2oktpI7q3PH2ecfPGf9n06dOlYWq6fGQxlRSSeCOh/H/P1rMtrqe0k3Qt5pj6Rufm/A96TVthKV9y9qk8enySrDKVhk&#43;Yw9drDufX8Pasv&#43;2j/wA9z/35FU7y6/tG7IxuMhAYDjZ1zx&#43;FH9jRf7X50Bc//9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/nvme/20230408_204511_res_hu43516cdb8668a12f12b3ea1f05263d5c_436164_600x600_fit_q90_r270_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
					
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/nvme/20230408_211735_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>6.7mm f/1.8 1/50sec ISO 200"
						

						
					
					>
					<img			
						width="450" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAGAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ALUNtGttLpsdrH5kikeVtGxgf4V9gT/XvynjfVAtxbW9lIsbg4lO4jLY45HcDP6VFq&#43;sHR9JWTzFfUJGbyRGc&#43;VH0wxPU47&#43;9ctHerfRNvtDISxyBLtZSe4JBzkjv/XlobJ9L1u90SSN5ExayzFHZw2046kH14rov&#43;E7032/76P&#43;FVjqtpcaUNLkgljeVAhYlSIs/KrbgeuT&#43;hrN/wCEST/oOSf9/qbKV0Y93512wm3MJo1AKE5AHt7f56VDZwvc3aLEFjmJxzjb75zxj2q3JMiONzcZ&#43;SReqn/Pb/JeNQishNH5Ki6mT5ZAeCM/w/X0/wAiRC3Xlx2TQsGt7gSkTFCQG2kgcdj/AC7VnfJ/z83H/f3/AOtVcGXUbg7pi0aISWBzz/Co/HFJ9iuf&#43;eT/APfApiP/2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/nvme/20230408_211735_res_hu56624e996b56981b76cdec0dcbc623bb_464411_600x600_fit_q90_r270_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-2");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>Third, the installation of a 330W UPS from APC, allowing graceful shutdown in case of power outages and protection from potential power surges.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-3-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-3" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/ups/1_ups_res.jpg" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="450"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AL1qQwFQ69qMWmwxOAHnBJRCfYjJqvaalagD9&#43;n51zfiLUIZ9RmZZVYYAGD7Csk0aSTLGhefqd3cvJcOJZA5D5PynaORjp&#43;Faug3k19paSTtvdSVZsdcGsLw1eQQRzSzKHRVkJGe232q/wCF72yTSmDTpH&#43;9YhTk4H1xVuS5SUnckOnWjxhYLCCH1K5NZGoeFHlZpbVir/3W6H/Cult&#43;gqwvU1we0lud3s4vQ4S2sdTthLCdPnYsrL9w7eRjrVnTNPvLO1Zbi3K5bOAc4rs2/pVG5&#43;6amdVtWHCkou5//9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/ups/1_ups_res_hu1a161ca91e3ac2cccc634b7bf858ba3d_182636_600x600_fit_q90_lanczos.jpg"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/ups/2_ups_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>6.7mm f/1.8 0.02sec ISO 640"
						

						
					
					>
					<img			
						width="338" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAEgMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AM7xDax2vi251IOVliZNmGx1UDI/WodH1a9vNYMbTu8Wwsyudx/M/Wq/iC7F7JZXyHK3K5POcMGIIz7YqXwpA3n3EzqRlQqk9/XH6VhFOKtLc6GtdDqd1G6mUZo0KOY8JzwyRPYXVv5sBk3xyOvyhvT2/wD11097Ja2sIWXAP8Cr1z7VhXWp2Vi4sLNEnuVABVB8kQzjn1x6Vjaa&#43;qHW7gajJ5qtz5zcAegX29qirapUc7mtNuEFGx0oub0gELHjtnOaPtF9/di/WqZ1O4DEIqbQflyO1J/al1/dT8qXtYB7KZ//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/ups/2_ups_res_huf71a6b935fc345b86480270ad6e6bd23_144654_600x600_fit_q90_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-3");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>Fourth, the installation of a Noctua NH-L12S cooler to pull down the temperature levels of the CPU.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-4-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-4" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
					
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/cooler/1_20230414_082641_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>9mm f/2.4 1/40sec ISO 250"
						

						
					
					>
					<img			
						width="600" height="450"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOZ0uzvNZkVXtH8pH&#43;aUcDIGcKc8H/Gun1K6hWOKKSKG63gZjILLM2M577W5HI4zmsjw/qdrb6YYGui0isXILbVjJHOD36ds8k9KSed/tbTuMD7kJ65B5J/I/m1S2WtS3PpFpeKRZPucnDQSkZP&#43;6e/41z95YyxERHI2ttBbKyRk8AZ9PrWx9pPnEyAMtr8zlhnfIR0H5D/vk&#43;tTaZqFzex3QvVS7hilaON9oWXHOcMT0HHfn1prUbOWez2HMWJEOfkPamwyy2MgmhcgRfNsdSR&#43;Xb8Pzq7D/rP&#43;An&#43;VU7r/AJbf9cGprUh6Ei6sL20eGK38sqDja2fmPf8AAcfjXb2OhxJo9tbyP5U0ZEpl/wBrrtPt2rzjResn1/rXrcn3PxrCs7JJESk0f//Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/cooler/1_20230414_082641_res_huf87a463cb09a0cea23be80e2f1f1a80b_474943_600x600_fit_q90_r180_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
					
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/cooler/2_20230414_082705_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>9mm f/2.4 1/30sec ISO 500"
						

						
					
					>
					<img			
						width="450" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAGAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ALNtqUEMKG4DAkfLsG7djrj1pX16xmOIlnGTgEx4ya4zStUuNLldY0VtygYkchcsc5J7d66P&#43;27zyw8VrbbM/KQrMR7Ajj1/MUSqSXQcYRZTN1qFtr4njiTzDGI1R2HzL17d8itT&#43;29b/wCgfD/30a5yfVWfUkuLqKN2jicIEY/K5ztJ&#43;hP55pn9v3/94/8AfVJarUGtTDvNRuLZ1t1kkimhJV8N/h361tCKZ7RLg3s/zICN0pAyRWgvgfTVYec93McdRhR&#43;WKG8KaTbn95eyQ8cB5l/lipcospQkZTx/wCjsZrmNwOceZkmqebb&#43;6n/AH0K2joGhhs/2hdSf7KAY/UYp39iaF/z0vfyj/wqk/ITR//Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/cooler/2_20230414_082705_res_hu49ab095f1864478d40c29bb9b66e2441_398705_600x600_fit_q90_r270_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
					
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/cooler/3_20230530_225224_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>9mm f/2.4 1/33sec ISO 1250"
						

						
					
					>
					<img			
						width="450" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAGAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOasr0uRPLbuohg&#43;zySA5yNm0foR&#43;Qqq7wnR4bQTgNHcNIu5SN6kDp1Gcj1qe1uXmW7tGwI5Zgdu0ZHI6H8BVtNMji8OXV48MfmGZQueBjAzj3y2fwocrbglcii1OYad/Z/2UqpBDSnjgmqf2aP/AJ6fr/8AWqxfLENOMS&#43;WZHZVAQZPJHfpWb/Y83/PJ6asSoLsaj6bfaUrXl3biNJmygDBvfnHHY//AFquyTLN4VWP/VymbLox&#43;ZsEc49MAVrXenajEzSW87SRBi4g2jGfoev1rn7&#43;4MtiZTpv2W6E2zyVOExjJbbiptc1fukkSreXVnbWyAqlyjyFB8u0HJ5PWuu&#43;xWvp/KuV0LRb&#43;8lS6uJ5IYl&#43;6V&#43;XPso/rXSf2Mn/AD&#43;Xf/f0f4Um0gje2x//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/cooler/3_20230530_225224_res_hudf69c4cf3ed8ba448c812763d788cb4e_411171_600x600_fit_q90_r270_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-4");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>Lastly, a RAM upgrade to 64GB after experiencing memory shortage when working with GNS3. 32GB wasn’t enough when running multiple containers and spawning multiple VMs on top of GNS3.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-5-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-5" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			
				
				
				
				
				
				
				
				
					
				
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/ram/1_ram_res.jpg" 
					class="galleryImg"
					
						

						
							data-description="SM-G998U1 + <br/>6.7mm f/1.8 1/100sec ISO 250"
						

						
					
					>
					<img			
						width="450" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAGAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AMIV0WnwaXp1rG2oQLLLI3mZIzsA6fh&#43;eTn0rCjLWul3WprAZ2hAWNAMhWP8bf7K/wA8UQa5b3slu92wjl4Uyof3TEDAwOx49xnHToYZtGLabtoja1XQ0u5pZ7NI1XJOYz8vXoy/wn36H2rK/sC89I/&#43;&#43;q2bvUhYtGkL7J0XMm3og7L&#43;XFQf8JTcf89T/wB8CnYzuZV08sCoLWVlMaboxCeS3Tk9sZ/8e96ff&#43;HYptPS5kmt7G8dQJSVxBITxyB9089Rx7Cucg1SaNik7PyNpJ&#43;8v0zU814VtIoRctLGMlFzwvvQ1cqEnF3T1LYSOxto7NJPOdMmWUHIZvQew6D8aZ5orPFz70v2g0xH/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/ram/1_ram_res_hufdd28577ce19d830899ab8bcd38bcc78_482657_600x600_fit_q90_r270_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			
				
					
				
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/ram/2_ram_res.jpg" 
					class="galleryImg"
					
						

						
							data-description=" + <br/>mm f/ sec ISO "
						

						
					
					>
					<img			
						width="499" height="600"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIACAAGwMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOR1vTGtNVEV5dCIPCGJRSQT0IAz&#43;NRQRWVvqEQs7iWUksrFkAGMcY9f89a63wF4fj8TwTT6rEZ5bc7S0jsScnOT9ckf8Brup/BumraultZ21ufLPzhFBB9zjNaRnaNmOpHmbaPMreBp47lCTnyjt9jkYrnhpaP8zXBBPUEcg9&#43;9eqnwpa29rdE6jBloWAA5rzeVVnlaQzRJk/dM4U&#43;nTFZO19QpxdrIk8C&#43;ImsNXEX2uW3im2q7g/dGRk/kTXrF1rGg2VtNJPLdX3lozNlic4HOOgr53s5fJuo3JwM4J9AeDXa3HiS0FkIpmYvJDscDtlcVbvbQzk3dHV3F00tncKGyWiOK89TRVIO642EEggoexx6VbHiuKWIWwjPKbC2awpHhEjAIMZ9TSsFNNRsz/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/ram/2_ram_res_huca1ae1b4e8d54e36d067af99f25c9a74_475419_600x600_fit_q90_lanczos.jpg"
						

						
							
								
							
						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-5");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<h2 id="services">Services</h2>
<p>Talking about the services, I am running just a handful. For the monitoring stack I have Telegraf, InfluxDB and Grafana to monitor resource utilization on the Proxmox box. I also have UptimeKuma providing a neat and simple dashboard for monitoring service uptime.</p>




	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-6-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-6" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/monitoring/1_uptimekuma_res.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="331"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABIAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APNo9St1t4UmsoJGjXG478kc9cSD19BVG5kSa4aRI1iU9EXOB&#43;ZJ/Wp5j/oNqNuPlPODz8x/D8qrVdyUkMwPU0cVYthmQ5GePf8ApUtwoEDHaR/31/WkO6FnVRp9mQACUOTjr87VUq5cf8g6y/65t/6G1U6bJRNbAGQ5GeKluVAgbAH5VFa/60/7tTXX/Hu34VLB7n//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/monitoring/1_uptimekuma_res_hu1a8cd94fc8c4692e0bc15b97fcd4c373_160624_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/monitoring/2_influxdb_res.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="331"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABIAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APOr&#43;ZOJFOSSCQRx1&#43;tUGYTsA8a5OBu5yP1qT5ppY1kIjDEDcQcVfsdBnv3k&#43;xg3BjxkowQD/vrFdDTk9EZpqK1Mh7eNRw/fH86fH5aIcwJLlerbuPfgitmfQr62tRcT2pEYILEyIe&#43;PX1NVI1i8uQ&#43;SWwhAwobHv9KXJKL1ViuaLV4u5XlACrwOv9a6TwjI8Zutjsududpx61zkv3E&#43;v9a6Hwn1uf8AgP8AWtaP8RGNX&#43;Gy3q8sh0WUGRiMDgn/AGqwrV3TTm2sVyGBwcZra1b/AJA0v0/9mrEt/wDkHH6NW1R&#43;&#43;vQyp/A/U//Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/monitoring/2_influxdb_res_hu1a8cd94fc8c4692e0bc15b97fcd4c373_556669_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/monitoring/3_grafana_res.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="318"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABEAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APMzGzcgL&#43;LCmmB/Uf8AfYpWA6fN93kEf4UERngLkle2etMBBA46Ef8AfQoMTqM7gMejCpCsAgwUPm7s55wBiogqE9&#43;/rQIP8KQdaX/CkHWmBO/T/gJqGP734Gpn6f8AATUMf3vwNAH/2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/monitoring/3_grafana_res_hu63c49fef1e2dae93cad841d816f78d1b_253743_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-6");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<p>For resource monitoring of my Unraid box, I just use the built-in dashboard which already gives me all the information I need such as CPU and disk temps, CPU, disk, and memory utilization, and power consumption.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-7-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-7" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/monitoring-unraid/1_unraid-mon.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="332"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABIAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APR00LRizbtFsDzwfsyf1p8nh3RNpI0exBwcYtk/wq8DhSdoyG9KUOSSD6daAMoeHtCDwBtJsSxB4NtHlunPT/Oalt/D2jKmTo9iG/69UH9KvIJF2ZkUg9c9TUgOOGbJ7cYoAoo7E4LHHXrTyzAE5PT1qOP734U89DTAZPI4CEOw/Gk82Qx/6xunrST/AHUpB/q/woA//9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/monitoring-unraid/1_unraid-mon_hue41aad0413aa76a74a02c2bf36d14a4b_582667_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/monitoring-unraid/2_unraid-mon.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="332"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABIAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APR4tA0Vix/sfTyd2M/ZkP8ASpG8O6Jt50ew4/6dU/wq8rgjnI2se9LuUggHOeaAMweHtCkAI0Wx9/8ARYx/SpV8PaKuCujWAx/07J/hV8HKjGRTf4h8pPPU0AZyyyYb9433vWpUdjv&#43;Y/nUC9G/3qmT&#43;OmApkfaPnbr60wSPtb526nvSn7o&#43;tMH3W/GgD//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/monitoring-unraid/2_unraid-mon_hue41aad0413aa76a74a02c2bf36d14a4b_504967_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-7");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>For productivity and utilities, I have Guacamole for VM and command line remote access, Krusader for file management within Unraid, Visual Studio Code for modifying configuration files and blogging, Firefox for VM-less browser access, Wiki.js for saving important information and notes taking of anything related to the Homelab and the projects I am working on, Jdownloader for HTTP downloads (mainly ISO files), Heimdall as my homelab dashboard, and Traefik as my reverse proxy!</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-8-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-8" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/1_guac.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="271"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAA4AIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AO58Z6h4o0oW58K6Nb3zPnzhIn3R2/iWql3e&#43;N7rwIlzb2CWuvmUb4I0TCrk9N5I6Y711looZnZcBc4K7RVvav8AdH5UragcNoUnjtvAmpyatF/xPxI/2NdkIyu1ccD5eu7rUnw&#43;fxrO2ojxlEFUeX9lBSIZ&#43;9v&#43;5/wHrXa7V/uj8qY5RCMr19qYH//Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/1_guac_hu4c837487343b5fe3682e8a3334c827b7_103706_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/2_krusader.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="410"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABYAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AO8i8O6fOP8AkG2m4cn90Of0oOgaYkpT&#43;yrXI7&#43;WMfyrdth/o68H86qzf8fbdT9SPagZjQeGoZFIEFmCR3tF4/SpP&#43;EST/nlZf8AgIv&#43;Fb1oP9FTg9PWp8H0P51XMyeVGdHemNSvlKQnXmmvKryZMR3MM8ScfyqD/ntT/wDlov8Aun&#43;lQUMS51COIBZbXAOBmFj/AOz077Vqe4r5tnkDP&#43;ob/wCLpp/1X/A/60//AJat/u/1quZk8qP/2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/2_krusader_huaaafed7fe20202f61a24db53af45dc7c_194670_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/3_vsc.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="302"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APMJDnYfb&#43;tStymD0z0pkgRVRWVg4HPPvTyRt69/WgCPA9KUAc8dqTPvS8j1oA//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/3_vsc_hu3d37b6522c29224fef3ad43ec2887029_135962_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/4_wikijs.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="304"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AIvB/h3R9Q8RRW91p8M0TI5KSDIPyk816DJ4E8LRQrjQrGPJ9AoP51yHgP8A5GqD/rm//oJr0&#43;cBoQTzg969HMIxjWSS6HDgZSlSbb6nPR&#43;BvCUp2SaHp5Pbo2amHw88IjpoNkPpHW0uVOUjjBBxkKBViSVIYjJI21VHJrz99jtP/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/4_wikijs_hu10ff007e12759842d19c799afe3059c7_113635_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/5_jdownloader.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="301"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APSxbXmBlDywzyOn51MLe5VgEGFx7VaW6jbgA5&#43;o/wAaeJgT91qogqGG52nrn2xUEdpdOpExlHPaQj&#43;RrT8z/ZP6U1plAIIwcdyP8adwsf/Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/5_jdownloader_hu38b1bf95a3a937b3ec4197e4618f69ab_163272_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/6_heimdall.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="297"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOP07wo15Ym6GoafGQCfIkuAspx/s479q6Cy8LtaQRr5&#43;h3Akb77uHK59T2FcnbanslEhClh0JAq/baukduYP3KqxGT5KcAe2K6PQyN3UfCT3RVFutEt2RvmKSBFZcdQe/NcjLpbB3QKcp&#43;taMut744f9TiPjb5a5xknjjjrVWfWXLSyKRuYcHA4oXmht3P/2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/6_heimdall_hu6065ae11d5c1c2c1a3aee256cc67c41e_501701_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/utils/7_traefik.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="447"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABgAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APL3RcpulCluG&#43;9x9f8A61IIYj5n&#43;lINn3eG&#43;f6cfzxWhImnfZlbzFD7RjacknbzkY45xTLNbJ4n89kBz3OCBjqPU57VWt7XMfark5rMywSrBlOCDkEdqfLNLM26WRnbGMsc1ehFmL0AuDDk4Ld&#43;DjPH0ovFs1P7hwWz8wByo4HQ/XNF3a9y&#43;Zc/LYYsUUh3OQPlznPU4qNY4yDlR16&#43;lJ/CKB3qSx7xQpOVXDqDgE96HhhEQYY3FiNvoMCmdxQepoA//9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/utils/7_traefik_hu1e1757ea255f0316f25464b84ef4cd8d_72653_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-8");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>For media services, I have Jellyfin for transcoding and serving media both at home and when on-the-go. To populate my fiance and I&rsquo;s media inventory with videos from our favorite youtube channels, I use <a href="https://github.com/jmbannon/ytdl-sub">ytdl-sub</a>. This automatically downloads the videos of any defined youtube channel, manages the specified retention period, and adds the necessary metadata for a nice and smooth feel when browsing in Jellyfin. And since the videos are played back locally, this means we also get ad-free content when watching. For legal downloading of media, I have deluge. Since I don&rsquo;t use this often, I still transfer files manually to the Jellyfin directory.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-9-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-9" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/media/1_jf.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="299"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOGtdLt5Eie8v3hV4g5O3IBPQfXHNSroKmZY/thUORsLRdRgmr9voccVnpdxfa3LZxXMG5dzn5OmAB6HioY9MtYoorg37b95O9LtfmTBJ4AJB6Dv1qKlRKbgjSEbw531IbnRbC2ht5G1QO0km2SNcBo1yRuOeOCPWs68s1tYLiSO5YmOYIikD5lO7n/x2r19ZaU2nG5s7m5kmMjK0cjjLjLHPTpwuevJNUr7T0g0pLndKGZxwx478dOo/qaFd9SdFuj/2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/media/1_jf_huaba3c1dda0a76a1868af9be81be38773_929179_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/media/2_jf_tv.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="303"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOV8NaVDqd2Eu9Plli&#43;z7zs3gqdyAE88/eqjqNlZ2bxoHfLTTRyDhigV8DjjtnrnpXT&#43;HvCvhxra0n1W9TdLDudftGAMgEYA574OfQ1xsq6ZFq8sHzNbrNIFdX5wDxj2x/OojNNtFqk4RV3ctJbWUtrabxJbGTcXnZdynjjGPerV/o1ra&#43;EotViecTySBcYzHjJHX146c1Ys08M34t4vsa23BLyGZyxIBPrjngdOuK5jVY4oNVuYLdw0EcrBCDkEZ61t7NqHPfqZuac&#43;Wx//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/media/2_jf_tv_hu0e30bbe655af32bdd924dafb51a46566_696393_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/media/3_ytdl-sub.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="304"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APMJD9wjuP61P1jxxz71FJtVERlbcBzzTyy7OefxoAYcDjatAA54HSkJHalwfSgD/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/media/3_ytdl-sub_hu03a5145121c36bad98aaaf8ff801c5aa_156101_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-9");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>I am aware I am still lacking in the automated media management department by making use of the *ARR services, but I can’t find time to set them up especially now that this homelab environment keeps me branching out to different projects all at the same time. At the moment I just have bigger fish to fry.</p>
<h2 id="vms">VMs</h2>
<p>As for the VMs, I only have quite a few. My main workstation is running PopOS based on Ubuntu. I do use a Macbook at home but still login with RDP to this machine almost all the time since it allows me anytime-anywhere remote access and I can easily pick up where I left off when I am working on something.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-10-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-10" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/popos/1_popos.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="375"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABQAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/ALPiH4dwaLo0&#43;om5E/klR5RTG7LAZzk461w7fZ1JC2QB7EOTivbfiCCPBd/nnJjx/wB9rXijHjo361cqkm76fcgSICsZ624x9TXY&#43;Gvh1/bWm2mpfaGEc5bciwqQoDFTklwe2eneuQLr2XP4mvbfhun/ABRFk2Tg&#43;ZgZ/wCmjURqNPZfcgaPMdW&#43;IWvanpstreNbywSS7GTyscKQRyDnqKpq8LWglNpDu8sN1bqfxrDuP9Qf&#43;u7VsJ/yDx/1wX&#43;lbVopJWRKepO32fy7hvsUGY42ZfvdRn39qhsviX4i0exSxsHtobePOxPJBxkknk89Sakf/VXv/XF//Zq4&#43;XvU0Ypt3NI6xP/Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/popos/1_popos_huaec8ce792172fe736a0955555a12f132_287881_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-10");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>Though 99% in shutdown state, I also keep a Windows 10 VM in case I need to use software which can’t run on Linux. I also keep a staging environment running on Debian for the remote tailscale exit node installed back home in Manila. Another one is an Ubuntu VM running GNS3 server for other side projects on kubernetes and networking. My VM disks are created in the NVMe drives allowing me to play around with VMs efficiently in terms of very quick load times. The NVMe drives are also mirrored in RAID1 so I don&rsquo;t have to worry about losing data when one of the two drives crashes.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-11-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-11" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/vms/1_vms.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="191"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAAoAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOwT4ceE5Fy2kKT05mk/&#43;Kpf&#43;FaeESOdHX/v9J/8VXSRfex29KmwPQUkNqzOUHw08I4H/EnXn/ptL/8AFU5fhx4UXkaSAQeP30v/AMVXU4HoKMD0FMR//9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/vms/1_vms_hua9e2729e8b72699486f64cb80d6c2ffb_57210_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-11");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>The last but not the least is my router! Running as a VM on Proxmox, it just works wonderfully. I did experience random reboots though, but this got fixed after upgrading the kernel from 5.4 to the new 6.1 together with the intel micro-code package. My longest uptime with it was around 40 days before I had to reboot for maintenance work. Inside OPNsense I am running Unbound caching DNS resolutions for faster downstream queries. The browsing experience became significanly better after enabling this. Websites started to load faster also after enabling DNS over HTTPS. I was trying to find an explanation to this but I will just leave it out in the cold for now. I also have my Cloudflare Dynamic DNS agent running here. For VPN, I have Wireguard allowing me unfiltered access to the entire network. I also use this on daily basis — tunneling at the very least my DNS traffic to Pihole for internet ads blocking.</p>
<p>



	





































<style>
	

	
</style>





<div id="gallery-ae85206290481cf425f0de9e51bc13d9-12-wrapper" class="gallery-wrapper">
<div id="gallery-ae85206290481cf425f0de9e51bc13d9-12" class="justified-gallery">
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/opnsense/1_proxmox.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="172"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIAAkAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOEnk3GIsVYkDI59qgeNWySqg4OOfeol&#43;8v1qaT/AFR&#43;jfzoAhSQROGXCsOQRUpvpQdwkJPqarN1/AfyptAH/9k="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/opnsense/1_proxmox_hu404439e683d15f1a256076f01f33b5d1_114853_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/opnsense/2_pihole.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="341"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABIAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/AOJS/laVFuGeaIfeQucH8Kc1zZCQsLMFSCNvpVQD98NvWrhN6EyLZiP&#43;uX/1q0bbjYx5XGanFbfd92w63vLCFHSaw8xieGPBWoJJ7d9ypblAWyCPTPTFJPJMshE0KhgTnKinpJcnIWAfd5xGOn5Viqai7/qVUlOorSS/L9Cr0k44q19quP8AnvL/AN9mqh/1lTVqNpPck&#43;0THrM//fRpDPNgjzXwevzGmUGgLI//2Q=="
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/opnsense/2_pihole_huc1baf80b03675390fa184597999e401c_134483_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
		
		
				
			
			
			
				
			

			
			


			
			
			

			
			


			<div>
				
				
					
				
				<a href="/posts/state-of-the-network-the-first-120-days/opnsense/3_opnsense.png" 
					class="galleryImg"
					
					>
					<img			
						width="600" height="302"

						
							
							style="filter: blur(25px);"
							
								src="data:image/jpeg;base64,/9j/2wCEAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIfIiEmKzcvJik0KSEiMEExNDk7Pj4&#43;JS5ESUM8SDc9PjsBCgsLDg0OHBAQHDsoIig7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O//AABEIABAAIAMBIgACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5&#43;gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4&#43;Tl5ufo6ery8/T19vf4&#43;fr/2gAMAwEAAhEDEQA/APS5PC&#43;hMihtIsCc43G3X1&#43;lNTwvoIYp/Ymn4HQ/ZVP9K1Xzt6/xH&#43;dJlg5IUkE45x&#43;dAGYfDGhKTjRtO4x/y6r/AIVc/s6yihSJbWER42BFT5QMdMelWXDEHA6470sgJCYycN60Af/Z"
							
							class="lazy"
							data-src="/posts/state-of-the-network-the-first-120-days/opnsense/3_opnsense_hu9a5b718c683341ed8bca172d4a1f4c76_139117_600x600_fit_q90_lanczos_3.png"
						

						
					>
				</a>
			</div>
		
	
</div>
</div>

<script>
	if (!jQuery) {
		alert("jquery is not loaded");
	}

	$( document ).ready(() => {
		const gallery = $("#gallery-ae85206290481cf425f0de9e51bc13d9-12");
		

		
		let swipeboxInstance = null;

		
		
		gallery.on('jg.complete', () => {
			
				
				
				$(() => {
					$('.lazy').Lazy({
						visibleOnly: true,
						afterLoad: element => element.css({filter: "none", transition: "filter 1.0s ease-in-out"})
					});
				});
			

			swipeboxInstance = $('.galleryImg').swipebox(
				jQuery.extend({},
					{  }
				)
			);
		});

		
		gallery.justifiedGallery({
			rowHeight : "150",
			margins : "5",
			border : 0,
			randomize :  false ,
			waitThumbnailsLoad : false,
			lastRow : "justify",
			captions : false,
			
			
		});

		
		
	});
</script>

<br></p>
<p>I think that&rsquo;s all of it for the network&rsquo;s status quo. Over the next few weeks I will have to wrap my head around Terraform, Ansible, and Kubernetes. This is because I&rsquo;ll be migrating most, if not all, of these services to a &ldquo;production&rdquo; k8s cluster with the help of automation. I&rsquo;ve been sitting on the fence about this for quite some time now, but I finally decided go with it to have hands-on experience with Infrastructure-as-Code. Is it necessary? Not really, but it sure is interesting.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Keepalived with Pihole for DNS HA</title>
      <link>https://luislogs.com/posts/keepalived-with-pihole-for-dns-ha/</link>
      <pubDate>Sun, 02 Jul 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/keepalived-with-pihole-for-dns-ha/</guid>
      <description>In my previous post about my DNS, I mentioned there that I migrated Pihole from Unraid to my Proxmox hosting my router. But in fact, on top of that, I left an instance of Pihole on Unraid running inside a LXC container. Together with that I also configured keepalived for high availability. Hosting the DNS on the same hypervisor as my router should already be sufficient (I&amp;rsquo;d say my OPNsense VM is more likely to face issues than a LXC container) but I still wanted to try out an use case for keepalived.</description>
      <content:encoded><![CDATA[<p>In my previous post about my DNS, I mentioned there that I migrated Pihole from Unraid to my Proxmox hosting my router. But in fact, on top of that, I left an instance of Pihole on Unraid running inside a LXC container. Together with that I also configured keepalived for high availability. Hosting the DNS on the same hypervisor as my router should already be sufficient (I&rsquo;d say my OPNsense VM is more likely to face issues than a LXC container) but I still wanted to try out an use case for keepalived.</p>
<h3 id="install-gravity-sync">Install Gravity Sync</h3>
<p>Keep in mind that the following IP addresses were used for the setup:</p>
<table>
<thead>
<tr>
<th>IP address</th>
<th>Hostname</th>
<th>Host</th>
</tr>
</thead>
<tbody>
<tr>
<td>10.0.0.80</td>
<td>pihole-ha-ip</td>
<td>-</td>
</tr>
<tr>
<td>10.0.0.81</td>
<td>pihole1b</td>
<td>Proxmox LXC</td>
</tr>
<tr>
<td>10.0.0.81</td>
<td>pihole2b</td>
<td>Unraid LXC</td>
</tr>
</tbody>
</table>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/pihole-proxmox.png" alt="Proxmox Pihole">
  </p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/pihole-unraid.png" alt="Unraid Pihole">
  </p>
<p>I already had one pihole instance running on 10.0.0.80. I just had to shut this down to test my new HA-configured pihole.</p>
<p>To keep the configuration of both piholes in sync, we can install <a href="https://github.com/vmstan/gravity-sync/wiki/Installing">gravity-sync</a>. I faced permission issues when I ran this as root. Make sure you have <code>PermitRootLogin yes</code> set in the <code>/etc/ssh/sshd_config</code> file. Then only execute below installation script.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sSL https://raw.githubusercontent.com/vmstan/gs-install/main/gs-install.sh <span class="p">|</span> bash
</span></span></code></pre></div><p>The installation procedure is straightforward. Just input the required information and wait for it to complete. You can then conduct a quick test of pulling or pushing configuration.</p>
<p>Create a new domain in pihole1 and ensure it&rsquo;s not reflected on pihole2.</p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/keepalived_test.png" alt="Test configuration">
  </p>
<p>You can then execute <code>gravity-sync compare</code> to see if there is any configuration mismatch.</p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/gravity_compare.png" alt="Gravity Sync Compare">
  </p>
<p>Then you can execute <code>gravity-sync pull</code> from the pihole2 and check if the delta configuration is reflected.</p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/gravity_pull.png" alt="Gravity Sync Pull">
  </p>
<h3 id="automate">Automate</h3>
<p>Execute <code>gravity-sync auto</code> on both pihole instances.</p>
<p>By default pihole should sync after 5 mins. For my setup I will set it hourly.</p>
<p><code>gravity-sync auto hour</code></p>
<h3 id="install-keepalived">Install keepalived</h3>
<p>I found this tutorial on reddit <a href="https://www.reddit.com/r/pihole/comments/d5056q/tutorial_v2_how_to_run_2_pihole_servers_in_ha/">link here</a> shared by <a href="https://www.reddit.com/user/Panja0/">Panja0</a> on how to make use of keepalived by monitoring the pihole-FTL service with a simple bash script. I wanted to try and do it from scratch to add to my knowledge but I have decided to park this for now and test out this tutorial. For those interested, the keepalived documentation can be found <a href="https://keepalived.readthedocs.io/en/latest/installing_keepalived.html">here</a>.</p>
<p>Install libipset13 and keepalived.</p>
<p><code>yum install -y libipset13 keepalived</code></p>
<p>Create a new scripts directory in /etc.</p>
<p><code>mkdir /etc/scripts</code></p>
<p>Create a new file and copy-paste the content from <a href="https://pastebin.com/npw6tcuk">https://pastebin.com/npw6tcuk</a>.</p>
<p>Add permision to execute the file:</p>
<p><code>chmod u+x /etc/scripts/chk_ftl</code></p>
<p>You need to edit keepalived.conf on both pihole instances. This file is located in <code>/etc/keepalived/</code>. The config files can be downloaded in the following links:
<a href="https://pastebin.com/nsBnkShi">keealived.conf for master</a>
<a href="https://pastebin.com/HbdsUc07">keealived.conf for master</a></p>
<p>Modify the following fields according to your IP configuration. The auth_pass field is a password that should be match between both configuration files.
unicast_src_ip
unicast_peer
auth_pass
virtual_ipaddress</p>
<p>Restart the keepalived service and now the IP should be assigned to your primary pihole!</p>
<p><code>sudo systemctl restart keepalived</code></p>
<p>You should now be able to see DNS queries coming in.</p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/pihole2a-running.png" alt="">
  </p>
<h3 id="testing-for-auto-fail-over">Testing for auto fail-over</h3>
<p>Shutdown the other pihole. Now pihole2b started accepting traffic</p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/pihole-failover.png" alt="">
  </p>
<p>Let’s see if it will preempt. Poweron other pihole and check the keepalived. You can also check 10.0.0.80/admin (virtual ip) and see if it’s routed to the primary .</p>
<p>
    <img src="/posts/keepalived-with-pihole-for-dns-ha/pihole-preempt.png" alt="">
  </p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Deploying my first 4G EPC network</title>
      <link>https://luislogs.com/posts/deploying-my-first-4g-epc-network/</link>
      <pubDate>Sun, 25 Jun 2023 00:01:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/deploying-my-first-4g-epc-network/</guid>
      <description>For the past few weeks, I&amp;rsquo;ve been working on making our home network stable after experiencing random reboots on my router and bombing the connection at home just right before leaving for work. All problems have been fixed now since the start of this month so I&amp;rsquo;ve had the time to continue with this other home project. Continuing from where I got off on k3s, I finally attempted to run a 4G EPC network in a small virtualized cluster.</description>
      <content:encoded><![CDATA[<p>For the past few weeks, I&rsquo;ve been working on making our home network stable after experiencing random reboots on my router and bombing the connection at home just right before leaving for work. All problems have been fixed now since the start of this month so I&rsquo;ve had the time to continue with this other home project. Continuing from where I got off on k3s, I finally attempted to run a 4G EPC network in a small virtualized cluster.</p>
<p>Before going further, first, I&rsquo;d like to thank the author of the tutorial, Infinity Don over at Dev.to, for sharing this cool idea together with the docker images. Ever since my interest in virtualization and containerization started, I have been looking for a weekend past-time for getting my hands dirty with, and luckily I stumbled upon his <a href="https://dev.to/infinitydon/virtual-4g-simulation-using-kubernetes-and-gns3-3b7k">article here</a>.</p>
<p>The article details on how to get everything running but I somehow still faced few minor issues. I&rsquo;d still recommend to refer to the tutorial if you are someone who takes troubleshooting as a fun challenge.</p>
<p>I like recording everything I execute so if you have the intention of creating your own network and don&rsquo;t want to be spoiled, then I&rsquo;d suggest not to continue and just go read the tutorial above instead.</p>
<p>If you are just interested in how I got things working, then feel free to continue.</p>
<h2 id="the-objective">The objective</h2>
<p>In bullet points:</p>
<ul>
<li>Create a cluster for running EPC components as simple as possible.</li>
<li>Use k3s as the kubernetes platform to have a smaller resource footprint.</li>
<li>Use Calico as the CNI instead of flannel (comes with k3s by default).</li>
<li>Use GNS3 for network simulation so I can start getting familiar with it for future projects.</li>
<li>Learn packet core!</li>
</ul>
<h2 id="vms-and-networking">VMs and Networking</h2>
<p>
    <img src="/posts/deploying-my-first-4g-epc-network/20230625_2.png" alt="GNS3 network">
  </p>
<p>The k3s cluster is running on Ubuntu 22.04 VMs. Openairinterface5G as the RAN and UE simulator as in the tutorial, though both are bifurcated into two VMs (the tutorial makes use of a single VM with the help of a second loopback address). For the latter, Ubuntu 18.04 was used to avoid any incompatibility issue since the documentation stated only this version. All Ubuntu VMs are assigned 4GB RAM. Ubuntu 22 VMs are assigned 2 vCPUs, and the two Ubuntu 18 VMs, with 4 vCPUs to speed up the build time of the simulator. For the router, the same Vyos router is used with separate connections for the management interface and the internet. I could have made use of the management interface as my internet gateway but I faced slow throughput when downloading packages on the VMs. The suggestion I got in the GNS3 forum is to use a NAT interface instead.</p>
<h2 id="preparing-the-environment">Preparing the environment</h2>
<p>I am running a remote GNS3 server inside another Ubuntu VM. For this I had to enable nested virtualization (Intel VT-x in my case) in the BIOS. I also had to passthrough the CPU instruction set extensions to my GNS3 host, and from the host to the Ubuntu 18.04 VMs, to clear some errors I faced in the initial attempt of building the eNB and UE simulator. To make it easier I just configured CPU passthrough on both my hypervisor and the GNS3 server.</p>
<p>You can check if your VMs are having the CPU extended instruction set flags using the command below:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat /proc/cpuinfo <span class="p">|</span> grep -i avx
</span></span></code></pre></div><p>VM images were created with already updated packages so I don&rsquo;t have to keep on updating everytime I have to re-instantiate a VM. For updating manually:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt-get update -y <span class="o">&amp;&amp;</span> sudo apt-get upgrade -y 
</span></span></code></pre></div><p>As for the kubernetes platform, I used k3s. It comes with flannel as the CNI but it can be installed with Calico. The steps I followed for this are logged in another <a href="https://luislogs.com/posts/install-k3s-with-calico-and-disable-traefik/">post</a>.</p>
<h2 id="vyos-configuration">Vyos configuration</h2>
<p>Configuring VyOS is fairly simple though prior CLI experience with routers such as cisco and the likes will surely help. The documentation can be found <a href="https://docs.vyos.io/en/equuleus/installation/virtual/gns3.html">here</a> for installing Vyos on GNS3, and the configuration guide in this <a href="https://docs.vyos.io/en/latest/configuration/index.html">link</a>.</p>
<p>To provide internet connectivity to my VMs I had to masquerade internal VM IPs towards the NAT GW. A static default route is set towards this GW, and the rest of routes are mainly for management access from the different external VLANs I have in my local network.</p>
<p>As for the BGP configuration, the command in the tutorial seems to be a little outdated. The following commands were used to enable BGP:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">set</span> protocols bgp neighbor 10.200.0.12 remote-as <span class="m">63400</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> protocols bgp system-as <span class="m">63400</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> protocols bgp neighbor 10.200.0.12 address-family ipv4-unicast 
</span></span></code></pre></div><p>I faced some minor timing issue when merging pcap files. To fix, all I had to do was to ensure the same NTP server is used across all nodes.</p>
<p>Snippet of my Vyos configuration:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">interfaces <span class="o">{</span>
</span></span><span class="line"><span class="cl">    ethernet eth0 <span class="o">{</span>
</span></span><span class="line"><span class="cl">        address 10.200.0.1/24
</span></span><span class="line"><span class="cl">        hw-id 0c:0a:6b:f7:00:00
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    ethernet eth1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">        address 172.16.0.1/24
</span></span><span class="line"><span class="cl">        hw-id 0c:0a:6b:f7:00:01
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    ethernet eth2 <span class="o">{</span>
</span></span><span class="line"><span class="cl">        hw-id 0c:0a:6b:f7:00:02
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    ethernet eth3 <span class="o">{</span>
</span></span><span class="line"><span class="cl">        address 10.20.0.20/24
</span></span><span class="line"><span class="cl">        hw-id 0c:0a:6b:f7:00:03
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    ethernet eth4 <span class="o">{</span>
</span></span><span class="line"><span class="cl">        address dhcp
</span></span><span class="line"><span class="cl">        hw-id 0c:0a:6b:f7:00:04
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    loopback lo <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">nat <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">source</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">        rule <span class="m">100</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">            outbound-interface eth4
</span></span><span class="line"><span class="cl">            <span class="nb">source</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">                address 10.200.0.0/24
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">            translation <span class="o">{</span>
</span></span><span class="line"><span class="cl">                address masquerade
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        rule <span class="m">101</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">            outbound-interface eth4
</span></span><span class="line"><span class="cl">            <span class="nb">source</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">                address 172.16.0.0/24
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">            translation <span class="o">{</span>
</span></span><span class="line"><span class="cl">                address masquerade
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">protocols <span class="o">{</span>
</span></span><span class="line"><span class="cl">    bgp <span class="o">{</span>
</span></span><span class="line"><span class="cl">        neighbor 10.200.0.12 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            address-family <span class="o">{</span>
</span></span><span class="line"><span class="cl">                ipv4-unicast <span class="o">{</span>
</span></span><span class="line"><span class="cl">                <span class="o">}</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">            remote-as <span class="m">63400</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        system-as <span class="m">63400</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    static <span class="o">{</span>
</span></span><span class="line"><span class="cl">        route 0.0.0.0/0 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 192.168.122.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        route 10.0.0.0/24 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 10.20.0.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        route 10.10.0.0/24 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 10.20.0.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        route 10.30.0.0/24 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 10.20.0.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        route 10.120.0.0/24 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 10.20.0.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        route 10.130.0.0/24 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 10.20.0.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        route 10.140.0.0/24 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            next-hop 10.20.0.1 <span class="o">{</span>
</span></span><span class="line"><span class="cl">            <span class="o">}</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">service <span class="o">{</span>
</span></span><span class="line"><span class="cl">    ntp <span class="o">{</span>
</span></span><span class="line"><span class="cl">        allow-client <span class="o">{</span>
</span></span><span class="line"><span class="cl">            address 0.0.0.0/0
</span></span><span class="line"><span class="cl">            address ::/0
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">        server ntp.ubuntu.com <span class="o">{</span>
</span></span><span class="line"><span class="cl">            prefer
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl">    ssh <span class="o">{</span>
</span></span><span class="line"><span class="cl">        port <span class="m">22</span>
</span></span><span class="line"><span class="cl">    <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><h2 id="installing-open5gs">Installing Open5gs</h2>
<p>Once the environment is ready, then it&rsquo;s time to install Open5gs. Clone the repository to your local directory from <a href="https://bitbucket.org/infinitydon/virtual-4g-simulator/src/master/open5gs/">Infinity Don&rsquo;s repository</a>.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://bitbucket.org/infinitydon/virtual-4g-simulator/src/master/open5gs/
</span></span></code></pre></div><p>The yaml files are based on older versions of kubernetes, so to make this work with the latest one at the time of this writing, that is v1.26.3, I had to modify hss-database/mongo-statefulset.yaml. Just update the apiVersion to <code>rbac.authorization.k8s.io/v1</code> (remove <code>beta1</code>).</p>
<p>I had to specify the mongodb version as well in hss-database/monogo-statefulset.yaml to avoid mongodb going to crashloopback state (reference <a href="https://stackoverflow.com/questions/64458588/crashloopbackoff-mongo-in-docker-kubernetes-failed-to-start-up-wiredtiger-un">here</a>).</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">      </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">mongo</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">mongo:4.2.10</span><span class="w">
</span></span></span></code></pre></div><p>Port 2123 on the SMF had to be opened to allow GTP-C connections with SGW. Update smf/smf-deploy.yaml and add the following.</p>
<p><strong>smf-deploy.yaml</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">gtpc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">2123</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">UDP</span><span class="w">
</span></span></span></code></pre></div><p>If BGP is to be used then this next step is optional. This how I established the connection of the eNB to the MME before the realizing I would need BGP eventually. Here I just modified the mme-deploy.yaml to expose the MME IP for the s1ap connectivity.</p>
<p><strong>mme-deploy.conf</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Service</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">open5gs-mme-svc-pool</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">namespace</span><span class="p">:</span><span class="w"> </span><span class="l">open5gs</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">epc-mode</span><span class="p">:</span><span class="w"> </span><span class="l">mme</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">#  - name: s1ap</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">#    port: 36412</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">#    protocol: SCTP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">#    nodePort: 36412</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">s6a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">3868</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">TCP    </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodePort</span><span class="p">:</span><span class="w"> </span><span class="m">30001</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">NodePort</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">selector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">epc-mode</span><span class="p">:</span><span class="w"> </span><span class="l">mme</span><span class="w">
</span></span></span></code></pre></div><p>The <strong>mme-configmap.yaml</strong> was also updated to set TAC to 1.</p>
<p>For the BGP configuration, the same yaml files from the tutorial were used. These yaml files are not present in the repository. Created a new directory and two yaml files with following configuration:</p>
<p><strong>calico-bgpconfig.yaml</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apiVersion: projectcalico.org/v3
</span></span><span class="line"><span class="cl">kind: BGPConfiguration
</span></span><span class="line"><span class="cl">metadata:
</span></span><span class="line"><span class="cl">  name: default
</span></span><span class="line"><span class="cl">spec:
</span></span><span class="line"><span class="cl">  asNumber: <span class="m">63400</span>
</span></span></code></pre></div><p><strong>calico-bgppeer.yaml</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apiVersion: projectcalico.org/v3
</span></span><span class="line"><span class="cl">kind: BGPPeer
</span></span><span class="line"><span class="cl">metadata:
</span></span><span class="line"><span class="cl">    name: bgppeer-vyos
</span></span><span class="line"><span class="cl">spec:
</span></span><span class="line"><span class="cl">    asNumber: <span class="m">63400</span>
</span></span><span class="line"><span class="cl">    peerIP: 10.200.0.1
</span></span></code></pre></div><p>Time to spin up the core! I tried to execute in small steps but then encountered pods getting stuck in crashloopback state. This is because each pod was trying to bring up the peer connectivity with other pods.</p>
<p>First create the namespace:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kubectl create ns open5gs
</span></span></code></pre></div><p>Then execute all at once!</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">kubectl apply -f hss-database/
</span></span><span class="line"><span class="cl">kubectl apply -f web-ui/
</span></span><span class="line"><span class="cl">kubectl apply -f hss/
</span></span><span class="line"><span class="cl">kubectl apply -f mme/
</span></span><span class="line"><span class="cl">kubectl apply -f upf
</span></span><span class="line"><span class="cl">kubectl apply -f sgw-u/
</span></span><span class="line"><span class="cl">kubectl apply -f sgw-c/
</span></span><span class="line"><span class="cl">kubectl apply -f smf/
</span></span><span class="line"><span class="cl">kubectl apply -f pcrf/
</span></span><span class="line"><span class="cl">kubectl apply -f nrf/
</span></span><span class="line"><span class="cl">kubectl apply -f calico/
</span></span></code></pre></div><p>Expect some pods to be restarting and wait until you see all in running state.</p>
<p>
    <img src="/posts/deploying-my-first-4g-epc-network/20230625_3.png" alt="k3s">
  </p>
<p>Check the WebUI if you are able to access with default credentials <code>admin</code> / <code>1423</code>.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/20230625_4.png" alt="HSS WebUI">
      <figcaption>HSS WebUI</figcaption>
    </figure>
  </p>
<h2 id="install-oaisim5g">Install OAISIM5G</h2>
<p>Next is to install the simulator. I exhausted a lot of time trying to make it work with the latest available version only to realize that the <a href="https://gitlab.eurecom.fr/oai/openairinterface5g/-/blob/develop/doc/L2NFAPI_S1.md">article</a> I was referring to is no longer valid after a certain development tag.</p>
<p>Download and extract the latest package suggested in the article:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">wget https://gitlab.eurecom.fr/oai/openairinterface5g/-/archive/2021.w51_c/openairinterface5g-2021.w51_c.tar.gz
</span></span><span class="line"><span class="cl">tar -zxvf openairinterface5g-2021.w51_c.tar.gz
</span></span></code></pre></div><h3 id="enodeb-configuration-file">enodeB configuration file</h3>
<p><strong>ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">    ////////// MME parameters:
</span></span><span class="line"><span class="cl">    <span class="nv">mme_ip_address</span>      <span class="o">=</span> <span class="o">(</span> <span class="o">{</span> <span class="nv">ipv4</span>       <span class="o">=</span> <span class="s2">&#34;10.200.0.11&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                              <span class="nv">ipv6</span>       <span class="o">=</span> <span class="s2">&#34;192:168:30::17&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                              <span class="nv">port</span>       <span class="o">=</span> <span class="m">30002</span> <span class="p">;</span>
</span></span><span class="line"><span class="cl">                              <span class="nv">active</span>     <span class="o">=</span> <span class="s2">&#34;yes&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                              <span class="nv">preference</span> <span class="o">=</span> <span class="s2">&#34;ipv4&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                            <span class="o">}</span>
</span></span><span class="line"><span class="cl">                          <span class="o">)</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">...                          
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">    NETWORK_INTERFACES :
</span></span><span class="line"><span class="cl">    <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_INTERFACE_NAME_FOR_S1_MME</span>            <span class="o">=</span> <span class="s2">&#34;ens4&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_IPV4_ADDRESS_FOR_S1_MME</span>              <span class="o">=</span> <span class="s2">&#34;172.16.0.30&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_INTERFACE_NAME_FOR_S1U</span>               <span class="o">=</span> <span class="s2">&#34;ens4&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_IPV4_ADDRESS_FOR_S1U</span>                 <span class="o">=</span> <span class="s2">&#34;172.16.0.30&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_PORT_FOR_S1U</span>                         <span class="o">=</span> 2152<span class="p">;</span> <span class="c1"># Spec 2152</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_IPV4_ADDRESS_FOR_X2C</span>                 <span class="o">=</span> <span class="s2">&#34;172.16.0.30&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">ENB_PORT_FOR_X2C</span>                         <span class="o">=</span> 36422<span class="p">;</span> <span class="c1"># Spec 36422</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="o">}</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl"><span class="nv">MACRLCs</span> <span class="o">=</span> <span class="o">(</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="nv">num_cc</span> <span class="o">=</span> 1<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_s_if_name</span>  <span class="o">=</span> <span class="s2">&#34;ens4&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">remote_s_address</span> <span class="o">=</span> <span class="s2">&#34;172.16.0.40&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_s_address</span>  <span class="o">=</span> <span class="s2">&#34;172.16.0.30&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_s_portc</span>    <span class="o">=</span> 50001<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">remote_s_portc</span>   <span class="o">=</span> 50000<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_s_portd</span>    <span class="o">=</span> 50011<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">remote_s_portd</span>   <span class="o">=</span> 50010<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">tr_s_preference</span> <span class="o">=</span> <span class="s2">&#34;nfapi&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">tr_n_preference</span> <span class="o">=</span> <span class="s2">&#34;local_RRC&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span></code></pre></div><p>Optional aliases for running OAISIM eNB and checking the logs:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">oaisimenb</span><span class="o">=</span><span class="s1">&#39;cd ~/openairinterface5g-2021.w51_c/cmake_targets/ran_build/build; sudo -E ./lte-softmodem -O ../../../ci-scripts/conf_files/rcc.band7.tm1.nfapi.conf &gt; enb.log 2&gt;&amp;1&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">oaisimenblogs</span><span class="o">=</span><span class="s1">&#39;tail -f ~/openairinterface5g-2021.w51_c/cmake_targets/ran_build/build/enb.log&#39;</span>
</span></span></code></pre></div><h3 id="ue-configuration">UE configuration</h3>
<p><strong>ci-scripts/conf_files/ue.nfapi.conf with your preferred editor</strong></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl"><span class="nv">L1s</span> <span class="o">=</span> <span class="o">(</span>
</span></span><span class="line"><span class="cl">        <span class="o">{</span>
</span></span><span class="line"><span class="cl">        <span class="nv">num_cc</span> <span class="o">=</span> 1<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">tr_n_preference</span> <span class="o">=</span> <span class="s2">&#34;nfapi&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_n_if_name</span>  <span class="o">=</span> <span class="s2">&#34;ens4&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">remote_n_address</span> <span class="o">=</span> <span class="s2">&#34;172.16.0.30&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_n_address</span>  <span class="o">=</span> <span class="s2">&#34;172.16.0.40&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_n_portc</span>    <span class="o">=</span> 50000<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">remote_n_portc</span>   <span class="o">=</span> 50001<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">local_n_portd</span>    <span class="o">=</span> 50010<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="nv">remote_n_portd</span>   <span class="o">=</span> 50011<span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="o">}</span>
</span></span><span class="line"><span class="cl"><span class="o">)</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">...
</span></span></code></pre></div><p>Optional aliases for running OAISIM UE and checking the logs:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">oaisimue</span><span class="o">=</span><span class="s1">&#39;cd ~/openairinterface5g-2021.w51_c/cmake_targets/ran_build/build; nohup sudo -E ./lte-uesoftmodem -O ../../../ci-scripts/conf_files/ue.nfapi.conf --L2-emul 3 --num-ues 1 --nums_ue_thread 1 &gt; ue.log 2&gt;&amp;1&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">oaisimuelogs</span><span class="o">=</span><span class="s1">&#39;tail -f ~/openairinterface5g-2021.w51_c/cmake_targets/ran_build/build/ue.log&#39;</span>
</span></span></code></pre></div><h3 id="building-the-simulators">Building the simulators</h3>
<p>When building the simulators the first time, it&rsquo;s important to execute with the <code>-I</code> flag so it will also install the package dependencies. If you are building without <code>-I</code> after a fresh Ubuntu install, you will face some errors:
e.g. for eNB:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./build_oai -c -I --eNB
</span></span></code></pre></div><p>e.g. for UE:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./build_oai -c -I --UE
</span></span></code></pre></div><h2 id="define-the-hss-profile-and-run-the-simulator">Define the HSS profile and run the simulator</h2>
<p>The UE information can be taken from <code>openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf</code>. This should be defined in the HSS via the WebUI.</p>
<p>
    <img src="/posts/deploying-my-first-4g-epc-network/20230625_5.png" alt="HSS WebUI">
  </p>
<p>Once that is done, fire up the eNB and the UE. I lose ssh access to the VM whenever I start the UE simulator . I have to resort to VNC access to initiate some traffic like ping or iperf. The VM should have the PGW provided IP assigned to oaitun_ue1.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/logs_smf.png" alt="UE IP">
      <figcaption>SMF logs</figcaption>
    </figure>
  </p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/ue_ip_a.png" alt="UE IP">
      <figcaption>UE IP</figcaption>
    </figure>
  </p>
<p>Below is a sample trace on the Vyos router for an UE ping request to the Google DNS. The first IP in each packet is the eNB IP and the second one of the UE&rsquo;s.</p>
<p>
    <img src="/posts/deploying-my-first-4g-epc-network/pcap_vyos_ping_ue-googledns.png" alt="Ping to Google DNS">
  </p>
<table>
<thead>
<tr>
<th>Packet No.</th>
<th>Event</th>
</tr>
</thead>
<tbody>
<tr>
<td>2563</td>
<td>eNB forwards to the Vyos router</td>
</tr>
<tr>
<td>2564</td>
<td>Vyos forwards to SGW</td>
</tr>
<tr>
<td>2565</td>
<td>GTP stripped off and worker-1 hosting UPF forwards ICMP to Vyos</td>
</tr>
<tr>
<td>2566</td>
<td>Vyos performs NAT and sends to internet</td>
</tr>
<tr>
<td>2567</td>
<td>Ping response received</td>
</tr>
<tr>
<td>2568</td>
<td>Response is forwarded to worker-1</td>
</tr>
<tr>
<td>2569</td>
<td>SGW forwards to Vyos the response encapsulated in GTP</td>
</tr>
<tr>
<td>2570</td>
<td>Vyos forwards to eNB</td>
</tr>
</tbody>
</table>
<p>Below some throughput testing to a public IPerf server. First one is from the VM&rsquo;s physical interface, second one over GTP.</p>
<p>
    <img src="/posts/deploying-my-first-4g-epc-network/iperf3.png" alt="Iperf to public server">
  </p>
<h2 id="my-sentiments">My Sentiments:</h2>
<p>I originally planned of avoiding BGP and save that for a later learning. But it was realized along the way that the eNB needs to be able to reach the pod IP address of the SGW. I initially configured a NAT on the Vyos router for this &ndash;  DNAT-ing UDP traffic for the uplink from the SGW Pod IP (<a href="https://www.etsi.org/deliver/etsi_ts/136400_136499/136413/15.03.00_60/ts_136413v150300p.pdf">3GPP TS 36.413</a>) to an exposed NodePort. While this worked with the eNB accepting the traffic, the response packets are coming out from a different SGW/worker source port. This shouldn&rsquo;t be the case. The response destination port must be copied from the request source port according to <a href="https://www.etsi.org/deliver/etsi_ts/129200_129299/129281/16.00.00_60/ts_129281v160000p.pdf">3GPP TS 29.281</a>. I tried to configure another NAT for the response but the Vyos router just dropped the packets. Enabling the NAT logs didn&rsquo;t help either because no logs were populating.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/s1ap_transportlayeraddress.png" alt="s1ap transport layer address">
      <figcaption>S1AP transport layer address</figcaption>
    </figure>
  </p>
<p>The solution was to resort to configuring BGP &ndash; exposing the Pod IP to the Vyos router so the eNB can reach SGW without any translation.</p>
<p>Talking about if this kind of setup will be helpful for learning EPC, I can&rsquo;t really say yet. I published this post before I forget the logistics and everything, though I&rsquo;m sure there&rsquo;s a lot more to explore and it does feel like I can do a lot more with it. I also do not have much experience on the packet core side of things so it&rsquo;s a bit hard to gauge but doing this project alone made me refer to 3GPP specs out of minimal curiousity. If playing around with these existing docker images will be tough, the option to install open5gs with VMs is always there. Another idea is to build docker images with the latest version of open5gs. In the end it all really depends on your objective. But whether what you plan to do is something simple or something complex, I am sure there will always be learning along the way.</p>
<h2 id="other-errors-faced">Other errors faced</h2>
<p>I was able to capture some of the errors (not all) faced during the deployment. One of the first ones that showed up is the AVX warning error in the first attempt of building the OAISIM5G simulator. I was clueless at first since google wasn&rsquo;t showing anything until I found a PDF stating that OAISIM5G needs a CPU that supports AVX. Realized that this must be listed under the extended instruction sets. So when I checked and found it there, I just had to make sure those flags are propagated all the way to my Ubuntu VMs.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/avx-error.png" alt="AVX warning error">
      <figcaption>AVX warning error</figcaption>
    </figure>
  </p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/avx-flags.png" alt="AVX flags">
      <figcaption>AVX in the CPU extended instruction sets</figcaption>
    </figure>
  </p>
<p>If you try to build the simulator without the <code>-I</code> flag, you will also face the following error. While you can also get away with it by manually installing the listed packages, it&rsquo;s just better to do it by the official documentation to avoid potential problems later on.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/package-dependency.png" alt="OAISIM build error ">
      <figcaption>OAISIM build error </figcaption>
    </figure>
  </p>
<p>At one point I could see tunneled interface getting created on the UE simulator but with no IP getting assigned. When I checked the SGW logs it was showing no response is getting received for create session request. This is where I had to open up port 2123 for the connection to go through.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/sgw-gtpc-connection-error.png" alt="SGW GTP-C connection error">
      <figcaption>SGW GTP-C connection error</figcaption>
    </figure>
  </p>
<p>Below is also a snapshot showing the UDP response for GTP of SGW-U coming out of a different source IP due to the worker node performing a NAT on the source Pod IP. While you may be able to find a work around with it by configuring another NAT, I&rsquo;ve had no luck trying to make it work. I retired from doing so since anyway a Pod IP (at least in this kind of setup) isn&rsquo;t really best paired with a NAT.</p>
<p>
    <figure>
      <img loading="lazy" src="/posts/deploying-my-first-4g-epc-network/sgw-diff-port.png" alt="SGW different source port">
      <figcaption>SGW response with a translated source IP</figcaption>
    </figure>
  </p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Replaced Swag with Traefik as my reverse proxy</title>
      <link>https://luislogs.com/posts/migrated-from-swarm-to-traefik-for-my-reverse-proxy/</link>
      <pubDate>Sun, 18 Jun 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/migrated-from-swarm-to-traefik-for-my-reverse-proxy/</guid>
      <description>I&amp;rsquo;ve been using Swag since I started with self-hosting. It&amp;rsquo;s been working flawlessly and I never had any issue with it. The only thing is if I wanted to expose a new service to the internet, I would have to configure it manually on a separate file. Swag already comes with the sample configuration files for most of popular services, though, it still felt like a chore I had to do before going to bed.</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been using Swag since I started with self-hosting. It&rsquo;s been working flawlessly and I never had any issue with it. The only thing is if I wanted to expose a new service to the internet, I would have to configure it manually on a separate file. Swag already comes with the sample configuration files for most of popular services, though, it still felt like a chore I had to do before going to bed. I started looking for alternatives and this is when I came to know more about Traefik. The first time I came across it was when I configured a small k3s cluster. It came by default but I just uninsatalled it due to lack of familiarity.</p>
<h3 id="looking-more-into-traefik">Looking more into Traefik</h3>
<p>I took reference from two sources to understand how Traefik works and how it can be used with my docker containers on Unraid. The yaml template I used is also sourced from the Ibracorp link.</p>
<ul>
<li><a href="https://doc.traefik.io/traefik/">Traefik documentation</a></li>
<li><a href="https://docs.ibracorp.io/traefik/master/unraid">Ibracorp tutorial</a></li>
</ul>
<p>In summary, Traefik can query docker via API with the help of container labels. Rules depend on those labels and so as long as you have the correct yaml configuration, you can treat it as set and forget. For those containers that you will be running in the times ahead, you just need to follow the same label structure.</p>
<p>The tutorial in the link includes configuring MFA by setting up a middleware. But I have a basic requirement of just providing external access to my services. So I will be saving this part for later in case I still require it in the future.</p>
<p>I had the following goals in mind:</p>
<ol>
<li>Be able to access containers named &lt;container_name&gt; externally from the internet via &lt;container_name&gt;.su-root.net.</li>
<li>Be able to access &lt;container_name&gt; externally from the internet via &lt;container_name&gt;.su-root.net.</li>
<li>Configure #1 and #2 with the least manual configuration required (but still secure).</li>
</ol>
<p>Given this, I will only go through the necessary configuration in as little footprint as possible.</p>
<h3 id="starting-with-traefik">Starting with traefik</h3>
<p>There are two different configuration files, a static one read at startup, and a dynamic one used during runtime.</p>
<p>Static configuration (traefik.yml) -&gt; Define the entry points, providers, certificate provider.</p>
<p>Dynamic coniguration (fileConfig.yml) -&gt; Define the routing and middleware.</p>
<p>There are multiple providers supported by Traefik but I will only focus on docker that is natively used by Unraid.</p>
<p>I can simply make use of the labels if I want to route traffic to specific containers that have multiple ports or those having a different container name against the cname I want to use.</p>
<h3 id="traefikyml-configuration">traefik.yml configuration</h3>
<p>The first part is to define the entry points where incoming traffic coming is expected.</p>
<ul>
<li>Define http entry point and redirect to https</li>
<li>Define https entry point to use a certificate generated by Let&rsquo;s Encrypt.</li>
<li>Define the middleware so we enforce the addition of STS header.</li>
</ul>
<p>Next is to define the providers:</p>
<ul>
<li>fileConfig.yml file that contains the dynamic routing configuration</li>
<li>Docker by quering using API via dockerproxy.</li>
</ul>
<p>Enable the UI and print info level logs.</p>
<p>And the last but not the least, the settings for Let&rsquo;s Encrypt, the certificate provider.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">global</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">checkNewVersion</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">sendAnonymousUsage</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">serversTransport</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">insecureSkipVerify</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">entryPoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">http</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;:80&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">http</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">redirections</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">entryPoint</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">to</span><span class="p">:</span><span class="w"> </span><span class="l">https</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">scheme</span><span class="p">:</span><span class="w"> </span><span class="l">https</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">https</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;:443&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">http</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">certResolver</span><span class="p">:</span><span class="w"> </span><span class="l">letsencrypt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">domains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">main</span><span class="p">:</span><span class="w"> </span><span class="l">mydomain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">sans</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="s1">&#39;*.mydomain.com&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">middlewares</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="s1">&#39;securityHeaders@file&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">providers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">providersThrottleDuration</span><span class="p">:</span><span class="w"> </span><span class="l">2s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">file</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/traefik/fileConfig.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">watch</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">docker</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">watch</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c"># Default host rule to containername.domain.example</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">defaultRule</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Host(`{{ lower (trimPrefix `/` .Name )}}.mydomain.com`)&#34;</span><span class="w">    </span><span class="c"># Replace with your domain</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">exposedByDefault</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">endpoint</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;tcp://dockersocket:2375&#34;</span><span class="w"> </span><span class="c"># Uncomment if you are using docker socket proxy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Enable traefik ui </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">api</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">dashboard</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">insecure</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">log</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">level</span><span class="p">:</span><span class="w"> </span><span class="l">INFO</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Use letsencrypt to generate ssl serficiates</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">certificatesResolvers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">letsencrypt</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">acme</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">email</span><span class="p">:</span><span class="w"> </span><span class="l">mail@mydomain.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">storage</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/traefik/acme.json</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">dnsChallenge</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">provider</span><span class="p">:</span><span class="w"> </span><span class="l">cloudflare</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c"># Used to make sure the dns challenge is propagated to the rights dns servers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">resolvers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="s2">&#34;1.1.1.1:53&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="s2">&#34;1.0.0.1:53&#34;</span><span class="w">
</span></span></span></code></pre></div><p>Before I go to the other next yaml file, it&rsquo;s important to note that I use IPvlan networking for all my docker containers. This provides a good level of network isolation against the host and I just find it way easier to manage my applications with unique IP addresses. The need to mention is due to the fact that I cannot get Traefik to detect the exposed port on the external IP address unless I explicitly define it with a label. I cannot find any mention of this in the documentation and I haven&rsquo;t done enough experiments to say that this works without a label when using a different network type such a bridge or a custom docker networks, and if it makes sense, even with an untagged ipvlan network.</p>
<p>Sample error I get without the loadbalancer label:</p>
<blockquote>
<p>&ldquo;level=error msg=&ldquo;service &quot;kuma&quot; error: port is missing&rdquo; providerName=docker container=kuma-cf32b&hellip;.&rdquo;</p>
</blockquote>
<h3 id="fileconfigyml-configuration">fileConfig.yml configuration</h3>
<p>Moving over to the dynamic configuration, if you want to route to non-docker services OR if for any reason you require specific routing for a container, you can define them here.</p>
<p>First, you have to specify the entry point for the router. Next is the rule that needs to fulfilled for this router to be activated. And third, the mapped service containing the destination and port.</p>
<p>The middleware you defined in the first yaml file will also be referenced from here. TLS options can also be in this file but it is not a requirement. I haven&rsquo;t gone through each of header but since I can see this enables STS, then I will just leave it as it is.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">http</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">routers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">opnsense</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">entryPoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">https</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">rule</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;Host(`opnsense.mydomain.com`)&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">opnsense</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">proxmox</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">entryPoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">https</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">rule</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;Host(`proxmox.mydomain.com`)&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">proxmox</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">opnsense</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">loadBalancer</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">servers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">https://10.100.0.1/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">proxmox</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">loadBalancer</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">servers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">https://10.100.0.2:8006/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">middlewares</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">securityHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">headers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">customResponseHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">X-Robots-Tag</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;none,noarchive,nosnippet,notranslate,noimageindex&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">X-Forwarded-Proto</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">customRequestHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">X-Forwarded-Proto</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">sslProxyHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">X-Forwarded-Proto</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">referrerPolicy</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;same-origin&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostsProxyHeaders</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="s2">&#34;X-Forwarded-Host&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">contentTypeNosniff</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">browserXssFilter</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">forceSTSHeader</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stsIncludeSubdomains</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stsSeconds</span><span class="p">:</span><span class="w"> </span><span class="m">63072000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stsPreload</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c"># Only use secure ciphers - https://ssl-config.mozilla.org/#server=traefik&amp;version=2.6.0&amp;config=intermediate&amp;guideline=5.6              </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">tls</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">default</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">minVersion</span><span class="p">:</span><span class="w"> </span><span class="l">VersionTLS12</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cipherSuites</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="l">TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305</span><span class="w">
</span></span></span></code></pre></div><h3 id="exposing-containers">Exposing containers</h3>
<p>Traefik will automatically and implicitly create a router and a service for each of the exposed container and the only thing you need is a set of labels:</p>
<ol>
<li>
<p>For traefik to detect the container
<code>traefik.enable=true</code></p>
</li>
<li>
<p>To define the allowed entry point
<code>traefik.http.routers.APP_NAME.entryPoints=https</code></p>
</li>
<li>
<p>So traefik knows to which port it has to route the packets
<code>traefik.http.services.APP_NAME.loadbalancer.server.port=APP_PORT</code></p>
</li>
<li>
<p>To tell traefik to use some another router name. (optional)
<code>traefik.http.routers.APP_NAME.rule=Host(\</code>APP_NAME.mydomain.com`)`</p>
</li>
</ol>
<p>The last one in the list is required only if you want traefik to route a sub-domain that is different from the container name. e.g. you want traefik to route kuma.mydomain.net to a container named uptime-kuma.</p>
<p>Below is an example of a container having three labels:</p>
<p>
    <img src="/posts/migrated-from-swarm-to-traefik-for-my-reverse-proxy/20230618_2.png" alt="Uptime-Kuma">
  </p>
<p>Make sure you have the respective cnames on your DNS pointing to Traefik, and once that is all set, you can start accessing your services over https. I would also suggest to test the redirection at least for the first service you are exposing.</p>
<p>When you have multiple services exposed, you might want to check out the Traefik UI to get a good visibility of your configuration. Do note that you will not be able to do any action from here and it&rsquo;s solely for checking the active routes.</p>
<p>
    <img src="/posts/migrated-from-swarm-to-traefik-for-my-reverse-proxy/20230618_1.png" alt="Uptime-Kuma">
  </p>
<p>Understanding Traefik might be a bit confusing at first but the more you read about the documentation, the more it gets interesting. Perhaps I&rsquo;ll be able to use more of its other functions in future projects!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Tailscale for tunneling torrent traffic to a remote server behind a NAT</title>
      <link>https://luislogs.com/posts/tailscale-for-tunneling-torrent-traffic-to-a-remote-server-behind-a-nat/</link>
      <pubDate>Sat, 20 May 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/tailscale-for-tunneling-torrent-traffic-to-a-remote-server-behind-a-nat/</guid>
      <description>I was finally able to deploy a remote server in my parent’s house with the help of my sister. Guided her to install Debian, connect the LAN, and download a script I created to get tailscale up and running. Once the server was connected to my tailscale network, I was able to ssh from there and do all the remaining configuration. The server is planned for 24/7 uptime and since I only intended this to act as an exit node, I just sourced a cheapo HP T620 Thinclient with 2-cores, 8GB RAM, and 128GB SSD from some online store back home.</description>
      <content:encoded><![CDATA[<p>I was finally able to deploy a remote server in my parent’s house with the help of my sister. Guided her to install Debian, connect the LAN, and download a script I created to get tailscale up and running. Once the server was connected to my tailscale network, I was able to ssh from there and do all the remaining configuration. The server is planned for 24/7 uptime and since I only intended this to act as an exit node, I just sourced a cheapo HP T620 Thinclient with 2-cores, 8GB RAM, and 128GB SSD from some online store back home.</p>
<p>When the remote server was all ready and configured together with VNC, I then created an LXC container, installed Deluge, and configured the tailscale client to use the remote server as an exit node.</p>
<p>
    <img src="/posts/tailscale-for-tunneling-torrent-traffic-to-a-remote-server-behind-a-nat/20230520_2.png" alt="Tailscale for tunneling torrent">
  </p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo tailscale up --exit-node<span class="o">=</span>&lt;tailscale_ip&gt; --exit-node-allow-lan-access<span class="o">=</span><span class="nb">true</span>
</span></span></code></pre></div><p>
    <img src="/posts/tailscale-for-tunneling-torrent-traffic-to-a-remote-server-behind-a-nat/20230520_3.png" alt="Tailscale for tunneling torrent">
  </p>
<p>Do note that setting “–exit-node-allow-lan-access” to true is required or else you wouldn’t be able to access the Deluge WebUI. This parameter will only recognize the local configured subnet so if your container is sitting inside a different VLAN like mine, then you will also need to configure an outbound NAT rule on your firewall or router. You should configure it in a way that any private local IP (outside the container subnet) that tries to reach your container, should have the Source IP translated to the Vlan interface IP of your router.</p>
<p>
    <img src="/posts/tailscale-for-tunneling-torrent-traffic-to-a-remote-server-behind-a-nat/20230520_4.png" alt="Tailscale for tunneling torrent">
  </p>
<p>I am sure there are other better ways to implement this but if you simply need a torrent client with tunneled traffic, then I believe this is the best and simplest it can be done.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Run Pihole in an LXC container in Proxmox</title>
      <link>https://luislogs.com/posts/run-pihole-in-an-lxc-container-in-proxmox/</link>
      <pubDate>Mon, 08 May 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/run-pihole-in-an-lxc-container-in-proxmox/</guid>
      <description>Pihole as our local DNS at home has been working perfectly fine. It blocks almost every ad there is whenever I am browsing. I was initially running it as a docker container within my Unraid server. The problem is every time I would restart Unraid for some experimental work, the internet of the entire house also goes down momentarily. I already tried defining a secondary DNS on my DHCP server but noticed some of my devices would randomly pick a DNS if there are multiple defined.</description>
      <content:encoded><![CDATA[<p>Pihole as our local DNS at home has been working perfectly fine. It blocks almost every ad there is whenever I am browsing. I was initially running it as a docker container within my Unraid server. The problem is every time I would restart Unraid for some experimental work, the internet of the entire house also goes down momentarily. I already tried defining a secondary DNS on my DHCP server but noticed some of my devices would randomly pick a DNS if there are multiple defined. Now that I have a Proxmox running OPNsense, I just thought of running Pihole there instead, since anyway I rarely restart that box.</p>
<p>Proxmox already supports LXC containers by default and in this case, running Pihole on LXC provides some advantage in terms of flexibility and ease of configuration. This is especially for those who have less experience working with docker but only with Linux in general. I will share one good use case for this later on but for now let’s start setting up Pihole on Proxmox.</p>
<p>The hardware requirements according to the pihole documentation:
Minimum of 2GB disk (4GB recommended)
512MB RAM</p>
<p>First you need to download an LXC template. I like using debian as the base image since it’s very lightweight and it’s where Ubuntu is based from. If you don’t have it yet, you can download it by going to Datacenter &gt; pve &gt; storage &gt; CT templates &gt; Templates and search for Debian 11 Bullseye.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_2.png" alt="alt text">
  </p>
<p>Click on Create CT and input a container ID, hostname, and the root password. Check Unprivileged container and nesting (optional). Note that nesting is not really required but in my case the proxmox terminal will keep on printing permission errors if I leave this unchecked.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_3.png" alt="alt text">
  </p>
<p>Select debian as the template.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_4.png" alt="alt text">
  </p>
<p>For disk, I assigned 6GB. For RAM, double the recommended, since I have enough.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_5.png" alt="alt text">
  </p>
<p>Assign a static IP to the container. Gateway should also be defined.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_6.png" alt="alt text">
  </p>
<p>For DNS I will assign my unbound IP which is the same as my OPNsense gateway IP. (Unbound is a DNS caching tool built-into OPNsense). This will basically be my upstream DNS for my Pihole. If you don’t have Unbound running then you can input any public DNS like Google (8.8.8.8, 8.8.4.4) or Cloudflare (1.1.1.1).</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_7.png" alt="alt text">
  </p>
<p>Confirm</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_8.png" alt="alt text">
  </p>
<p>Enable start on boot flag.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_9.png" alt="alt text">
  </p>
<p>Login as root</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_10.png" alt="alt text">
  </p>
<p>Update and upgrade</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apt-get update -y <span class="o">&amp;&amp;</span> apt-get upgrade -y
</span></span></code></pre></div><p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_11.png" alt="alt text">
  </p>
<p>Install curl:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">apt-get install curl -y
</span></span></code></pre></div><p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_12.png" alt="alt text">
  </p>
<p>Install Pihole:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sSL https://install.pi-hole.net <span class="p">|</span> bash
</span></span></code></pre></div><p>Install custom upstream and point to unbound IP</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_13.png" alt="alt text">
  </p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_14.png" alt="alt text">
  </p>
<p>Install the default blacklist.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_15.png" alt="alt text">
  </p>
<p>Install admin interface and lighthttpd.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_16.png" alt="alt text">
  </p>
<p>Query logging or any other option is fine.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_17.png" alt="alt text">
  </p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_18.png" alt="alt text">
  </p>
<p>Reset the pihole password.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo pihole -a -p
</span></span></code></pre></div><p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_19.png" alt="alt text">
  </p>
<p>Now go to your container IP and append /admin (e.g. http://10.0.0.88/admin)</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_20.png" alt="alt text">
  </p>
<p>If you are running it on proxmox like me you’d probably get the same error as in the snap below. You can ignore this especially if you have multi-core host. If you want to be sure you can check your CPU utilization with the top command.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_21.png" alt="alt text">
  </p>
<p>After changing your DNS to pihole, check with nslookup if your device is able to send and receive to and from the Pihole IP.</p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_22.png" alt="alt text">
  </p>
<p>
    <img src="/posts/run-pihole-in-an-lxc-container-in-proxmox/20230508_23.png" alt="alt text">
  </p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Virtualized OPNsense on Proxmox as my homelab router</title>
      <link>https://luislogs.com/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/</link>
      <pubDate>Tue, 25 Apr 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/</guid>
      <description>So this little thing arrived last week. Ever since I got my Unraid box up and running 24/7, I just felt I needed more control over the entire network. This is primarily because my existing home router would randomly drop packets and anyone who has planned to work from our home won’t be able to do so.
As for the specs, it’s a fanless appliance running a quad-core Intel 12th-gen J6412 (2 GHz base, 2.</description>
      <content:encoded><![CDATA[<p>So this little thing arrived last week. Ever since I got my Unraid box up and running 24/7, I just felt I needed more control over the entire network. This is primarily because my existing home router would randomly drop packets and anyone who has planned to work from our home won’t be able to do so.</p>
<p>
    <img src="/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/20230425_1.webp" alt="alt text">
  </p>
<p>
    <img src="/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/20230425_2.webp" alt="alt text">
  </p>
<p>As for the specs, it’s a fanless appliance running a quad-core Intel 12th-gen J6412 (2 GHz base, 2.6 GHz boost) with 5x Intel i226 2.5Gbe NICs. I chose the bare minimum option so I can avoid the crappy RAM and storage that might come with it. For the RAM I was able to source second-hand 2x8GB Samsung DDR4 SODIMMs and for the storage I didn’t any more bother and just ordered a 240GB SSD from Amazon since these come cheap these days.</p>
<p>
    <img src="/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/20230425_3.webp" alt="alt text">
  </p>
<p>Installed Proxmox and spawned a VM running a router software based on freeBSD called OPNsense. I can’t believe I’ve been missing on this piece of software for the longest time. It feels like I’ve rekindled my love for networking ever since I switched to a different role in my career graduating from configuring routers and switches.</p>
<p>
    <img src="/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/20230425_4.webp" alt="alt text">
  </p>
<p>
    <img src="/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/20230425_5.webp" alt="alt text">
  </p>
<p>The entire setup process was very straightforward. I just got confused a tad bit in the beginning when I was trying to figure out which interface to assign for management access. On my first attempt, I assigned the first interface in the list, expecting that it would be mapped to the first physical port. But when I tried to plug an ethernet cable from my laptop, for some reason I couldn’t ping the management IP I set. Long story short I re-installed Proxmox again only to know that the first installation was already correct. Maybe some lose cable?</p>
<p>
    <img src="/posts/virtualized-opnsense-on-proxmox-as-my-homelab-router/20230425_6.webp" alt="alt text">
  </p>
<p>Anyway the router has been running stable for the past week. This is with virtio running as a driver for the Intel i226 NICs. On average I’m getting about 500Mbps for internet (I used to get about 700MBps with a TP-Link A10 router and yes I can deal with that 200Mbps difference for now!). I’ll explore physically passing through the NICs later on once I get the time. But as far as I can tell, I’m just loving it. On top of that Proxmox has also been remarkably gaining my interest now that I have a pi-hole running in an LXC container.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Install k3s on Ubuntu Server 22.04</title>
      <link>https://luislogs.com/posts/install-k3s-on-ubuntu-server-22-04/</link>
      <pubDate>Sat, 15 Apr 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/install-k3s-on-ubuntu-server-22-04/</guid>
      <description>While working on creating my own kubernetes cluster I initially wanted to go with the official documentation for the installation process. But then I thought why not explore other distributions that can even simplify and reduce the time of the whole deployment process. This is when I came across k3s which claims to be an easier way of installing and managing kubernetes.
K3s makes use of containerd as the default container platform but I opted to go with docker since I want to become more familiar with it.</description>
      <content:encoded><![CDATA[<p>While working on creating my own kubernetes cluster I initially wanted to go with the official documentation for the installation process. But then I thought why not explore other distributions that can even simplify and reduce the time of the whole deployment process. This is when I came across k3s which claims to be an easier way of installing and managing kubernetes.</p>
<p>K3s makes use of containerd as the default container platform but I opted to go with docker since I want to become more familiar with it. Note that at this time docker is still considered experimental with k3s as written in the official documentation but I still went on with it anyway. In the following steps I also included how you can execute the kubectl commands without the need of sudo and how they can be executed from a remote machine.</p>
<h3 id="installation-on-master-node">Installation on master node</h3>
<p>I have the following setup at the moment where my cluster has a node subnet of 20.0.0.0/24.</p>
<p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_1.png" alt="alt text">
  </p>
<p>Before anything else, modify the hosts on file on each node to reflect the IP and hostnames of the your entire cluster:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">127.0.0.1 localhost
</span></span><span class="line"><span class="cl">20.0.0.10 k8s-master m
</span></span><span class="line"><span class="cl">20.0.0.11 k8s-worker-1 w1
</span></span><span class="line"><span class="cl">20.0.0.12 k8s-worker-2 w2
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_2.png" alt="alt text">
  </p>
<p>Update and upgrade ubuntu packages:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt upgrade
</span></span><span class="line"><span class="cl">sudo reboot
</span></span></code></pre></div><p>Install required tools and docker on both master and worker nodes. First add the docker repository.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
</span></span><span class="line"><span class="cl">curl -fsSL https://download.docker.com/linux/ubuntu/gpg <span class="p">|</span> sudo apt-key add -
</span></span><span class="line"><span class="cl">sudo add-apt-repository <span class="s2">&#34;deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable&#34;</span>
</span></span></code></pre></div><p>Install docker:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update <span class="o">&amp;&amp;</span> sudo apt install -y docker-ce
</span></span></code></pre></div><p>Run docker and enable persistence in case of server reboot:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl start docker
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> docker
</span></span></code></pre></div><p>Check if docker is running:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl status docker
</span></span></code></pre></div><p>Install k3s on the master node:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sfL https://get.k3s.io <span class="p">|</span> sh -s - --docker
</span></span></code></pre></div><p>Check status of k3s:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl status k3s
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_3.png" alt="alt text">
  </p>
<p>Check if node is running:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo kubectl get node -o wide
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_4.png" alt="alt text">
  </p>
<p>As an optional step, unblock ports used by kubernetes. By default firewall will be inactive but in case you have enabled it previously, then you need to perform the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw allow 6443/tcp
</span></span><span class="line"><span class="cl">sudo ufw allow 443/tcp
</span></span></code></pre></div><p>You can also check the status of your firewall with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ufw status
</span></span></code></pre></div><p>Disable with:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ufw disable
</span></span></code></pre></div><p>Extract the token to be used for joining worker nodes:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo cat /var/lib/rancher/k3s/server/node-token
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_5.png" alt="alt text">
  </p>
<h3 id="installation-on-worker-node">Installation on worker node</h3>
<p>Next is to install k3s on the worker nodes. Here you will need the master node IP address as well as the token from the previous step.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -sfL http://get.k3s.io <span class="p">|</span> <span class="nv">K3S_URL</span><span class="o">=</span>https://&lt;master_IP&gt;:6443 <span class="nv">K3S_TOKEN</span><span class="o">=</span>&lt;join_token&gt; sh -s - --docker
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_6.png" alt="alt text">
  </p>
<p>Verify all nodes are joined to the cluster</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo kubectl get nodes -o wide
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_7.png" alt="alt text">
  </p>
<p>Now you can try to deploy a test nginx pod</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo kubectl run --image nginx nginx-test
</span></span><span class="line"><span class="cl">sudo kubectl get pod nginx-test -o wide
</span></span></code></pre></div><p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_8.png" alt="alt text">
  </p>
<h3 id="permit-non-root-user-to-execute-kubectl-commands">Permit non-root user to execute kubectl commands</h3>
<p>Now if you try to execute kubectl commands without sudo, you would probably face the error below.</p>
<p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_9.png" alt="alt text">
  </p>
<p>This is because kubernetes will be installed with root credentials and any other user to execute kubectl will have to be permitted. The easy way is to copy the k3s.yaml file in the /etc/rancher/k3s directory to your user’s kube config file. First create the directory (with your non-root user) if you don’t have it yet. Note of the user and group variables:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir ~/.kube
</span></span><span class="line"><span class="cl">cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
</span></span><span class="line"><span class="cl">chown &lt;user&gt;:&lt;group&gt; ~/.kube/config
</span></span></code></pre></div><p>Then you have to export the kube config every time so to do this automatically upon login modify your .bashrc and add the line:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">KUBECONFIG</span><span class="o">=</span>~/.kube/config
</span></span></code></pre></div><p>For you to be able to execute kubectl commands with just typing ‘k’ you can also add the following:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">source</span> &lt;<span class="o">(</span>kubectl completion bash<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="nb">alias</span> <span class="nv">k</span><span class="o">=</span>kubectl
</span></span><span class="line"><span class="cl"><span class="nb">complete</span> -o default -F __start_kubectl k
</span></span></code></pre></div><p>Lastly if you want to be able to execute kubectl commands from a remote machine outside your cluster just ensure you have the same kube config file in the previous step and change the server IP from localhost to the actual one.</p>
<p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_10.png" alt="alt text">
  </p>
<p>
    <img src="/posts/install-k3s-on-ubuntu-server-22-04/20230415_11.png" alt="alt text">
  </p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Configure port forwarding on your home router</title>
      <link>https://luislogs.com/posts/configure-port-forwarding-on-your-home-router/</link>
      <pubDate>Mon, 20 Mar 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/configure-port-forwarding-on-your-home-router/</guid>
      <description>While setting up Nextcloud on my Unraid server, there was a part where I had to port forward incoming traffic to a reverse proxy. Here I will show you how to set it up on my TP-Link router.
The port forwarding function can be found in Advanced Settings &amp;gt; NAT forwarding &amp;gt; Virtual Server. Do note the name and location of this function can vary between brands and even models of the same brand.</description>
      <content:encoded><![CDATA[<p>While setting up Nextcloud on my Unraid server, there was a part where I had to port forward incoming traffic to a reverse proxy. Here I will show you how to set it up on my TP-Link router.</p>
<p>The port forwarding function can be found in Advanced Settings &gt; NAT forwarding &gt; Virtual Server. Do note the name and location of this function can vary between brands and even models of the same brand.</p>
<p>
    <img src="/posts/configure-port-forwarding-on-your-home-router/router_1.png" alt="alt text">
  </p>
<p>Here I just need to make a new entry to point the external port 443 to my Unraid internal IP with port 1443.</p>
<p>
    <img src="/posts/configure-port-forwarding-on-your-home-router/router_2.png" alt="alt text">
  </p>
<p>To put it simply how this works, anyone who tries to access your public IP address via https or port 443 will be redirected to whatever local IP and port you specify. Now you can try to access your external IP with http or whatever and your connection should be forwarded to the correct service. In the example below nc.su-root.net is pointing to my public IP and internally getting forwarded to Swag.</p>
<p>
    <img src="/posts/configure-port-forwarding-on-your-home-router/router_3.png" alt="alt text">
  </p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Configure Dynamic DNS to reach your home network</title>
      <link>https://luislogs.com/posts/configure-dynamic-dns-to-reach-your-network-at-home/</link>
      <pubDate>Sun, 12 Mar 2023 18:40:30 +0900</pubDate>
      
      <guid>https://luislogs.com/posts/configure-dynamic-dns-to-reach-your-network-at-home/</guid>
      <description>For this first post I want to start with the basic question — how do you reach your server at home with a dynamic public IP? I am almost sure that this is the most asked question when starting with self-hosting especially if you have the mindset of being able to access your environment anytime, anywhere. Well, at least for me, this is the very first question I had in mind when I was just starting back then.</description>
      <content:encoded><![CDATA[<p>For this first post I want to start with the basic question — how do you reach your server at home with a dynamic public IP? I am almost sure that this is the most asked question when starting with self-hosting especially if you have the mindset of being able to access your environment anytime, anywhere. Well, at least for me, this is the very first question I had in mind when I was just starting back then.</p>
<p>For us who don&rsquo;t want to pay more for a static IP, luckily there is a service called dynamic DNS. This is, for most of the time, free and should be supported by most modern home routers.</p>
<h3 id="what-is-dynamic-dns-ddns">What is Dynamic DNS (DDNS)?</h3>
<p>Let me explain this in layman&rsquo;s terms. First, DNS stands for domain name service. A domain is the name you type when you want to access a website such as <a href="https://www.google.com">www.google.com</a> or <a href="https://www.su-root.net">www.su-root.net</a>. Domains will always be mapped to a public IP address as long as it&rsquo;s registered.</p>
<p>Normally, a website will have a static public IP throughout its lifetime unless it is moved to a different server. For websites hosted by hosting companies such as AWS or Bluehost, the mapping of the IP address to a domain name is most of the time managed by them. This is as long as the domain provider is configured to use their nameservers.</p>
<p>For private hosts running behind a normal internet service provider, this is where DDNS comes into picture. If your ISP keeps changing your IP address (e.g. daily or weekly), then DDNS keeps track of this and updates their records automatically (as long as your router supports this feature). This is the best way for people who don&rsquo;t want to acquire a static IP that incur additional costs on their monthly bill.</p>
<h3 id="how-do-you-configure-dynamic-dns">How do you configure Dynamic DNS?</h3>
<p>Now let me walk you through how to configure it with the help of my home router.
Before anything else you need to create an account from a DDNS provider such as no-ip.</p>
<p>
    <img src="/posts/configure-dynamic-dns-to-reach-your-network-at-home/noip.png" alt="alt text">
  </p>
<p>From the Dashboard, go to &gt; Dynamic DNS &gt; No-IP Hostnames then click Create Hostname.</p>
<p>
    <img src="/posts/configure-dynamic-dns-to-reach-your-network-at-home/noip_2.png" alt="alt text">
  </p>
<p>Input your preferred hostname and select any of the free domains. Keep Record Type as DNS Host (A), input your current public IP address, and proceed to create the hostname. You can check your IP here if you don&rsquo;t know it yet.</p>
<p>Next is to configure the DDNS on the router.</p>
<p>What I have is a TP-Link Archer A10 from 3 years ago and it still works perfectly fine without any hiccup. Like I said, most modern routers should support DDNS, but if yours don&rsquo;t and you plan to walk the path of self-hosting, then you can get a new or even a used one for just a couple of bucks.</p>
<p>
    <img src="/posts/configure-dynamic-dns-to-reach-your-network-at-home/router.png" alt="alt text">
  </p>
<p>Login to your router&rsquo;s web GUI. This is, for 99% of the time, the same as your default gateway IP. Mine happens to be &ldquo;http://10.0.0.1&rdquo;. You can also check your current WAN IP from here.</p>
<p>
    <img src="/posts/configure-dynamic-dns-to-reach-your-network-at-home/router2.png" alt="alt text">
  </p>
<p>Next, go to the dynamic DNS configuration. In my case it&rsquo;s under Advanced Settings &gt; Network.
Select NO-IP, input your credentials and the newly created domain. Save.</p>
<p>From here on your router will keep updating your DDNS (No-IP) every time your IP address changes. To verify if your configuration is working, you can do a DNS look up and check if it&rsquo;s correctly mapped to your IP.</p>
<p>
    <img src="/posts/configure-dynamic-dns-to-reach-your-network-at-home/whois.png" alt="alt text">
  </p>
<p>This is the first step to the path of self-hosting and once you have the services running on your server, then you can expose them later on by port forwarding which I will be covering in a different post.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
