<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="profile" href="https://gmpg.org/xfn/11"> 
	<title>oriolrius.cat &#8211; Oriol Rius :: Technology : Crecimiento Personal : Mussol</title>
<meta name='robots' content='max-image-preview:large' />
<link rel='dns-prefetch' href='//oriolrius.cat' />
<link rel='dns-prefetch' href='//fonts.googleapis.com' />
<link href='https://fonts.googleapis.com' rel='preconnect' />
<link href='https://fonts.gstatic.com' crossorigin='anonymous' rel='preconnect' />
<link rel="alternate" type="application/rss+xml" title="oriolrius.cat &raquo; Feed" href="https://oriolrius.cat/feed/" />
<link rel="alternate" type="application/rss+xml" title="oriolrius.cat &raquo; Comments Feed" href="https://oriolrius.cat/comments/feed/" />
<link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://oriolrius.cat/wp-json/oembed/1.0/embed?url=https%3A%2F%2Foriolrius.cat%2F" />
<link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://oriolrius.cat/wp-json/oembed/1.0/embed?url=https%3A%2F%2Foriolrius.cat%2F&#038;format=xml" />
<style id='wp-img-auto-sizes-contain-inline-css'>
img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px}
/*# sourceURL=wp-img-auto-sizes-contain-inline-css */
</style>
<link rel='stylesheet' id='astra-theme-css-css' href='https://oriolrius.cat/wp-content/themes/astra/assets/css/minified/main.min.css?ver=4.13.3' media='all' />
<style id='astra-theme-css-inline-css'>
:root{--ast-post-nav-space:0;--ast-container-default-xlg-padding:2.5em;--ast-container-default-lg-padding:2.5em;--ast-container-default-slg-padding:2em;--ast-container-default-md-padding:2.5em;--ast-container-default-sm-padding:2.5em;--ast-container-default-xs-padding:2.4em;--ast-container-default-xxs-padding:1.8em;--ast-code-block-background:#ECEFF3;--ast-comment-inputs-background:#F9FAFB;--ast-normal-container-width:1200px;--ast-narrow-container-width:750px;--ast-blog-title-font-weight:600;--ast-blog-meta-weight:600;--ast-global-color-primary:var(--ast-global-color-4);--ast-global-color-secondary:var(--ast-global-color-5);--ast-global-color-alternate-background:var(--ast-global-color-6);--ast-global-color-subtle-background:var(--ast-global-color-7);--ast-bg-style-guide:var( --ast-global-color-secondary,var(--ast-global-color-5) );--ast-shadow-style-guide:0px 0px 4px 0 #00000057;--ast-global-dark-bg-style:#fff;--ast-global-dark-lfs:#fbfbfb;--ast-widget-bg-color:#fafafa;--ast-wc-container-head-bg-color:#fbfbfb;--ast-title-layout-bg:#eeeeee;--ast-search-border-color:#e7e7e7;--ast-lifter-hover-bg:#e6e6e6;--ast-gallery-block-color:#000;--srfm-color-input-label:var(--ast-global-color-2);}html{font-size:100%;}a{color:#ff6600;}a:hover,a:focus{color:var(--ast-global-color-1);}body,button,input,select,textarea,.ast-button,.ast-custom-button{font-family:'Ubuntu',sans-serif;font-weight:400;font-size:16px;font-size:1rem;line-height:var(--ast-body-line-height,1.65);}blockquote{color:var(--ast-global-color-3);}h1,h2,h3,h4,h5,h6,.entry-content :where(h1,h2,h3,h4,h5,h6),.site-title,.site-title a{font-family:'Ubuntu',sans-serif;text-decoration:initial;}.ast-site-identity .site-title a{color:var(--ast-global-color-2);}.site-title{font-size:26px;font-size:1.625rem;display:block;}.site-header .site-description{font-size:15px;font-size:0.9375rem;display:none;}.entry-title{font-size:20px;font-size:1.25rem;}.ast-blog-single-element.ast-taxonomy-container a{font-size:14px;font-size:0.875rem;}.ast-blog-meta-container{font-size:13px;font-size:0.8125rem;}.archive .ast-article-post .ast-article-inner,.blog .ast-article-post .ast-article-inner,.archive .ast-article-post .ast-article-inner:hover,.blog .ast-article-post .ast-article-inner:hover{border-top-left-radius:6px;border-top-right-radius:6px;border-bottom-right-radius:6px;border-bottom-left-radius:6px;overflow:hidden;}h1,.entry-content :where(h1){font-size:36px;font-size:2.25rem;font-family:'Ubuntu',sans-serif;line-height:1.4em;}h2,.entry-content :where(h2){font-size:30px;font-size:1.875rem;font-family:'Ubuntu',sans-serif;line-height:1.3em;}h3,.entry-content :where(h3){font-size:24px;font-size:1.5rem;font-family:'Ubuntu',sans-serif;line-height:1.3em;}h4,.entry-content :where(h4){font-size:20px;font-size:1.25rem;line-height:1.2em;font-family:'Ubuntu',sans-serif;}h5,.entry-content :where(h5){font-size:18px;font-size:1.125rem;line-height:1.2em;font-family:'Ubuntu',sans-serif;}h6,.entry-content :where(h6){font-size:16px;font-size:1rem;line-height:1.25em;font-family:'Ubuntu',sans-serif;}::selection{background-color:#ff6600;color:#000000;}body,h1,h2,h3,h4,h5,h6,.entry-title a,.entry-content :where(h1,h2,h3,h4,h5,h6){color:var(--ast-global-color-3);}.tagcloud a:hover,.tagcloud a:focus,.tagcloud a.current-item{color:#000000;border-color:#ff6600;background-color:#ff6600;}input:focus,input[type="text"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="password"]:focus,input[type="reset"]:focus,input[type="search"]:focus,textarea:focus{border-color:#ff6600;}input[type="radio"]:checked,input[type=reset],input[type="checkbox"]:checked,input[type="checkbox"]:hover:checked,input[type="checkbox"]:focus:checked,input[type=range]::-webkit-slider-thumb{border-color:#ff6600;background-color:#ff6600;box-shadow:none;}.site-footer a:hover + .post-count,.site-footer a:focus + .post-count{background:#ff6600;border-color:#ff6600;}.single .nav-links .nav-previous,.single .nav-links .nav-next{color:#ff6600;}.entry-meta,.entry-meta *{line-height:1.45;color:#ff6600;}.entry-meta a:not(.ast-button):hover,.entry-meta a:not(.ast-button):hover *,.entry-meta a:not(.ast-button):focus,.entry-meta a:not(.ast-button):focus *,.page-links > .page-link,.page-links .page-link:hover,.post-navigation a:hover{color:var(--ast-global-color-1);}#cat option,.secondary .calendar_wrap thead a,.secondary .calendar_wrap thead a:visited{color:#ff6600;}.secondary .calendar_wrap #today,.ast-progress-val span{background:#ff6600;}.secondary a:hover + .post-count,.secondary a:focus + .post-count{background:#ff6600;border-color:#ff6600;}.calendar_wrap #today > a{color:#000000;}.page-links .page-link,.single .post-navigation a{color:var(--ast-global-color-3);}.ast-search-menu-icon .search-form button.search-submit{padding:0 4px;}.ast-search-menu-icon form.search-form{padding-right:0;}.ast-header-search .ast-search-menu-icon.ast-dropdown-active .search-form,.ast-header-search .ast-search-menu-icon.ast-dropdown-active .search-field:focus{transition:all 0.2s;}.search-form input.search-field:focus{outline:none;}.ast-mobile-header-content .ast-builder-layout-element:not(.ast-builder-menu):not(.ast-header-divider-element),.ast-mobile-popup-content .ast-builder-layout-element:not(.ast-builder-menu):not(.ast-header-divider-element){padding:15px 20px;}.ast-search-menu-icon .search-form button.search-submit:focus,.ast-theme-transparent-header .ast-header-search .ast-dropdown-active .ast-icon,.ast-theme-transparent-header .ast-inline-search .search-field:focus .ast-icon{color:var(--ast-global-color-1);}.ast-desktop .ast-header-search .slide-search .search-form{border:2px solid var(--ast-global-color-0);}.ast-header-search .slide-search .search-field{background-color:var(--ast-global-dark-bg-style);}.ast-archive-title{color:#ff6600;}.widget-title{font-size:22px;font-size:1.375rem;color:#ff6600;}.single .ast-author-details .author-title{color:var(--ast-global-color-1);}.ast-single-post .entry-content a,.ast-comment-content a:not(.ast-comment-edit-reply-wrap a){text-decoration:underline;}.ast-single-post .elementor-widget-button .elementor-button,.ast-single-post .entry-content .uagb-tab a,.ast-single-post .entry-content .uagb-ifb-cta a,.ast-single-post .entry-content .uabb-module-content a,.ast-single-post .entry-content .uagb-post-grid a,.ast-single-post .entry-content .uagb-timeline a,.ast-single-post .entry-content .uagb-toc__wrap a,.ast-single-post .entry-content .uagb-taxomony-box a,.entry-content .wp-block-latest-posts > li > a,.ast-single-post .entry-content .wp-block-file__button,a.ast-post-filter-single,.ast-single-post .ast-comment-content .comment-reply-link,.ast-single-post .ast-comment-content .comment-edit-link{text-decoration:none;}.ast-search-menu-icon.slide-search a:focus-visible:focus-visible,.astra-search-icon:focus-visible,#close:focus-visible,a:focus-visible,.ast-menu-toggle:focus-visible,.site .skip-link:focus-visible,.wp-block-loginout input:focus-visible,.wp-block-search.wp-block-search__button-inside .wp-block-search__inside-wrapper,.ast-header-navigation-arrow:focus-visible,.ast-orders-table__row .ast-orders-table__cell:focus-visible,a#ast-apply-coupon:focus-visible,#ast-apply-coupon:focus-visible,#close:focus-visible,.button.search-submit:focus-visible,#search_submit:focus,.normal-search:focus-visible,.ast-header-account-wrap:focus-visible,.astra-cart-drawer-close:focus,.ast-single-variation:focus,.ast-button:focus,.ast-builder-button-wrap:has(.ast-custom-button-link:focus),.ast-builder-button-wrap .ast-custom-button-link:focus{outline-style:dotted;outline-color:inherit;outline-width:thin;}input:focus,input[type="text"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="password"]:focus,input[type="reset"]:focus,input[type="search"]:focus,input[type="number"]:focus,textarea:focus,.wp-block-search__input:focus,[data-section="section-header-mobile-trigger"] .ast-button-wrap .ast-mobile-menu-trigger-minimal:focus,.ast-mobile-popup-drawer.active .menu-toggle-close:focus,#ast-scroll-top:focus,#coupon_code:focus,#ast-coupon-code:focus{border-style:dotted;border-color:inherit;border-width:thin;}input{outline:none;}.ast-logo-title-inline .site-logo-img{padding-right:1em;}body .ast-oembed-container *{position:absolute;top:0;width:100%;height:100%;left:0;}body .wp-block-embed-pocket-casts .ast-oembed-container *{position:unset;}.ast-single-post-featured-section + article {margin-top: 2em;}.site-content .ast-single-post-featured-section img {width: 100%;overflow: hidden;object-fit: cover;}.ast-separate-container .site-content .ast-single-post-featured-section + article {margin-top: -80px;z-index: 9;position: relative;border-radius: 4px;}@media (min-width: 922px) {.ast-no-sidebar .site-content .ast-article-image-container--wide {margin-left: -120px;margin-right: -120px;max-width: unset;width: unset;}.ast-left-sidebar .site-content .ast-article-image-container--wide,.ast-right-sidebar .site-content .ast-article-image-container--wide {margin-left: -10px;margin-right: -10px;}.site-content .ast-article-image-container--full {margin-left: calc( -50vw + 50%);margin-right: calc( -50vw + 50%);max-width: 100vw;width: 100vw;}.ast-left-sidebar .site-content .ast-article-image-container--full,.ast-right-sidebar .site-content .ast-article-image-container--full {margin-left: -10px;margin-right: -10px;max-width: inherit;width: auto;}}.site > .ast-single-related-posts-container {margin-top: 0;}@media (min-width: 922px) {.ast-desktop .ast-container--narrow {max-width: var(--ast-narrow-container-width);margin: 0 auto;}}.ast-page-builder-template .hentry {margin: 0;}.ast-page-builder-template .site-content > .ast-container {max-width: 100%;padding: 0;}.ast-page-builder-template .site .site-content #primary {padding: 0;margin: 0;}.ast-page-builder-template .no-results {text-align: center;margin: 4em auto;}.ast-page-builder-template .ast-pagination {padding: 2em;}.ast-page-builder-template .entry-header.ast-no-title.ast-no-thumbnail {margin-top: 0;}.ast-page-builder-template .entry-header.ast-header-without-markup {margin-top: 0;margin-bottom: 0;}.ast-page-builder-template .entry-header.ast-no-title.ast-no-meta {margin-bottom: 0;}.ast-page-builder-template.single .post-navigation {padding-bottom: 2em;}.ast-page-builder-template.single-post .site-content > .ast-container {max-width: 100%;}.ast-page-builder-template .entry-header {margin-top: 2em;margin-left: auto;margin-right: auto;}.ast-page-builder-template .ast-archive-description {margin: 2em auto 0;padding-left: 20px;padding-right: 20px;}.ast-page-builder-template .ast-row {margin-left: 0;margin-right: 0;}.single.ast-page-builder-template .entry-header + .entry-content,.single.ast-page-builder-template .ast-single-entry-banner + .site-content article .entry-content {margin-bottom: 2em;}@media(min-width: 921px) {.ast-page-builder-template.archive.ast-right-sidebar .ast-row article,.ast-page-builder-template.archive.ast-left-sidebar .ast-row article {padding-left: 0;padding-right: 0;}}input[type="text"],input[type="number"],input[type="email"],input[type="url"],input[type="password"],input[type="search"],input[type=reset],input[type=tel],input[type=date],select,textarea{font-size:16px;font-style:normal;font-weight:400;line-height:24px;width:100%;padding:12px 16px;border-radius:4px;box-shadow:0px 1px 2px 0px rgba(0,0,0,0.05);color:var(--ast-form-input-text,#475569);}input[type="text"],input[type="number"],input[type="email"],input[type="url"],input[type="password"],input[type="search"],input[type=reset],input[type=tel],input[type=date],select{height:40px;}input[type="date"]{border-width:1px;border-style:solid;border-color:var(--ast-border-color);background:var( --ast-global-color-secondary,var(--ast-global-color-5) );}input[type="text"]:focus,input[type="number"]:focus,input[type="email"]:focus,input[type="url"]:focus,input[type="password"]:focus,input[type="search"]:focus,input[type=reset]:focus,input[type="tel"]:focus,input[type="date"]:focus,select:focus,textarea:focus{border-color:#046BD2;box-shadow:none;outline:none;color:var(--ast-form-input-focus-text,#475569);}label,legend{color:var(--ast-global-color-2,#111827 );font-size:14px;font-style:normal;font-weight:500;line-height:20px;}select{padding:6px 10px;}fieldset{padding:30px;border-radius:4px;}button,.ast-button,.button,input[type="button"],input[type="reset"],input[type="submit"]{border-radius:4px;box-shadow:0px 1px 2px 0px rgba(0,0,0,0.05);}:root{--ast-comment-inputs-background:#FFF;}::placeholder{color:var(--ast-form-field-color,#9CA3AF);}::-ms-input-placeholder{color:var(--ast-form-field-color,#9CA3AF);}@media (max-width:921.9px){#ast-desktop-header{display:none;}}@media (min-width:922px){#ast-mobile-header{display:none;}}.wp-block-buttons.aligncenter{justify-content:center;}@media (max-width:921px){.ast-theme-transparent-header #primary,.ast-theme-transparent-header #secondary{padding:0;}}@media (max-width:921px){.ast-plain-container.ast-no-sidebar #primary{padding:0;}}.ast-plain-container.ast-no-sidebar #primary{margin-top:0;margin-bottom:0;}.wp-block-button.is-style-outline .wp-block-button__link{border-color:#ff6600;}div.wp-block-button.is-style-outline > .wp-block-button__link:not(.has-text-color),div.wp-block-button.wp-block-button__link.is-style-outline:not(.has-text-color){color:#ff6600;}.wp-block-button.is-style-outline .wp-block-button__link:hover,.wp-block-buttons .wp-block-button.is-style-outline .wp-block-button__link:focus,.wp-block-buttons .wp-block-button.is-style-outline > .wp-block-button__link:not(.has-text-color):hover,.wp-block-buttons .wp-block-button.wp-block-button__link.is-style-outline:not(.has-text-color):hover{color:#ffffff;background-color:var(--ast-global-color-1);border-color:var(--ast-global-color-1);}.post-page-numbers.current .page-link,.ast-pagination .page-numbers.current{color:#000000;border-color:#ff6600;background-color:#ff6600;}.wp-block-buttons .wp-block-button.is-style-outline .wp-block-button__link.wp-element-button,.ast-outline-button,.wp-block-uagb-buttons-child .uagb-buttons-repeater.ast-outline-button{border-color:#ff6600;border-top-width:2px;border-right-width:2px;border-bottom-width:2px;border-left-width:2px;font-family:inherit;font-weight:500;font-size:16px;font-size:1rem;line-height:1em;padding-top:13px;padding-right:30px;padding-bottom:13px;padding-left:30px;}.wp-block-buttons .wp-block-button.is-style-outline > .wp-block-button__link:not(.has-text-color),.wp-block-buttons .wp-block-button.wp-block-button__link.is-style-outline:not(.has-text-color),.ast-outline-button{color:#ff6600;}.wp-block-button.is-style-outline .wp-block-button__link:hover,.wp-block-buttons .wp-block-button.is-style-outline .wp-block-button__link:focus,.wp-block-buttons .wp-block-button.is-style-outline > .wp-block-button__link:not(.has-text-color):hover,.wp-block-buttons .wp-block-button.wp-block-button__link.is-style-outline:not(.has-text-color):hover,.ast-outline-button:hover,.ast-outline-button:focus,.wp-block-uagb-buttons-child .uagb-buttons-repeater.ast-outline-button:hover,.wp-block-uagb-buttons-child .uagb-buttons-repeater.ast-outline-button:focus{color:#ffffff;background-color:var(--ast-global-color-1);border-color:var(--ast-global-color-1);}.ast-single-post .entry-content a.ast-outline-button,.ast-single-post .entry-content .is-style-outline>.wp-block-button__link{text-decoration:none;}.wp-block-button .wp-block-button__link.wp-element-button.is-style-outline:not(.has-background),.wp-block-button.is-style-outline>.wp-block-button__link.wp-element-button:not(.has-background),.ast-outline-button{background-color:transparent;}.uagb-buttons-repeater.ast-outline-button{border-radius:9999px;}@media (max-width:921px){.wp-block-buttons .wp-block-button.is-style-outline .wp-block-button__link.wp-element-button,.ast-outline-button,.wp-block-uagb-buttons-child .uagb-buttons-repeater.ast-outline-button{padding-top:12px;padding-right:28px;padding-bottom:12px;padding-left:28px;}}@media (max-width:544px){.wp-block-buttons .wp-block-button.is-style-outline .wp-block-button__link.wp-element-button,.ast-outline-button,.wp-block-uagb-buttons-child .uagb-buttons-repeater.ast-outline-button{padding-top:10px;padding-right:24px;padding-bottom:10px;padding-left:24px;}}.entry-content[data-ast-blocks-layout] > figure{margin-bottom:1em;}h1.widget-title{font-weight:inherit;}h2.widget-title{font-weight:inherit;}h3.widget-title{font-weight:inherit;}.elementor-widget-container .elementor-loop-container .e-loop-item[data-elementor-type="loop-item"]{width:100%;} .content-area .elementor-widget-theme-post-content h1,.content-area .elementor-widget-theme-post-content h2,.content-area .elementor-widget-theme-post-content h3,.content-area .elementor-widget-theme-post-content h4,.content-area .elementor-widget-theme-post-content h5,.content-area .elementor-widget-theme-post-content h6{margin-top:1.5em;margin-bottom:calc(0.3em + 10px);}#page{display:flex;flex-direction:column;min-height:100vh;}.ast-404-layout-1 h1.page-title{color:var(--ast-global-color-2);}.single .post-navigation a{line-height:1em;height:inherit;}.error-404 .page-sub-title{font-size:1.5rem;font-weight:inherit;}.search .site-content .content-area .search-form{margin-bottom:0;}#page .site-content{flex-grow:1;}.widget{margin-bottom:1.25em;}#secondary li{line-height:1.5em;}#secondary .wp-block-group h2{margin-bottom:0.7em;}#secondary h2{font-size:1.7rem;}.ast-separate-container .ast-article-post,.ast-separate-container .ast-article-single,.ast-separate-container .comment-respond{padding:3em;}.ast-separate-container .ast-article-single .ast-article-single{padding:0;}.ast-article-single .wp-block-post-template-is-layout-grid{padding-left:0;}.ast-separate-container .comments-title,.ast-narrow-container .comments-title{padding:1.5em 2em;}.ast-page-builder-template .comment-form-textarea,.ast-comment-formwrap .ast-grid-common-col{padding:0;}.ast-comment-formwrap{padding:0;display:inline-flex;column-gap:20px;width:100%;margin-left:0;margin-right:0;}.comments-area textarea#comment:focus,.comments-area textarea#comment:active,.comments-area .ast-comment-formwrap input[type="text"]:focus,.comments-area .ast-comment-formwrap input[type="text"]:active {box-shadow:none;outline:none;}.archive.ast-page-builder-template .entry-header{margin-top:2em;}.ast-page-builder-template .ast-comment-formwrap{width:100%;}.entry-title{margin-bottom:0.6em;}.ast-archive-description p{font-size:inherit;font-weight:inherit;line-height:inherit;}.ast-separate-container .ast-comment-list li.depth-1,.hentry{margin-bottom:1.5em;}.site-content section.ast-archive-description{margin-bottom:2em;}@media (min-width:921px){.ast-left-sidebar.ast-page-builder-template #secondary,.archive.ast-right-sidebar.ast-page-builder-template .site-main{padding-left:20px;padding-right:20px;}}@media (max-width:544px){.ast-comment-formwrap.ast-row{column-gap:10px;display:inline-block;}#ast-commentform .ast-grid-common-col{position:relative;width:100%;}}@media (min-width:1201px){.ast-separate-container .ast-article-post,.ast-separate-container .ast-article-single,.ast-separate-container .ast-author-box,.ast-separate-container .ast-404-layout-1,.ast-separate-container .no-results{padding:3em;}} .content-area .elementor-widget-theme-post-content h1,.content-area .elementor-widget-theme-post-content h2,.content-area .elementor-widget-theme-post-content h3,.content-area .elementor-widget-theme-post-content h4,.content-area .elementor-widget-theme-post-content h5,.content-area .elementor-widget-theme-post-content h6{margin-top:1.5em;margin-bottom:calc(0.3em + 10px);}.elementor-loop-container .e-loop-item,.elementor-loop-container .ast-separate-container .ast-article-post,.elementor-loop-container .ast-separate-container .ast-article-single,.elementor-loop-container .ast-separate-container .comment-respond{padding:0px;}@media (max-width:921px){.ast-left-sidebar #content > .ast-container{display:flex;flex-direction:column-reverse;width:100%;}}@media (min-width:922px){.ast-separate-container.ast-right-sidebar #primary,.ast-separate-container.ast-left-sidebar #primary{border:0;}.search-no-results.ast-separate-container #primary{margin-bottom:4em;}}.wp-block-button .wp-block-button__link{color:#000000;}.wp-block-button .wp-block-button__link:hover,.wp-block-button .wp-block-button__link:focus{color:#ffffff;background-color:var(--ast-global-color-1);border-color:var(--ast-global-color-1);}.elementor-widget-heading h1.elementor-heading-title{line-height:1.4em;}.elementor-widget-heading h2.elementor-heading-title{line-height:1.3em;}.elementor-widget-heading h3.elementor-heading-title{line-height:1.3em;}.elementor-widget-heading h4.elementor-heading-title{line-height:1.2em;}.elementor-widget-heading h5.elementor-heading-title{line-height:1.2em;}.elementor-widget-heading h6.elementor-heading-title{line-height:1.25em;}.wp-block-button .wp-block-button__link,.wp-block-search .wp-block-search__button,body .wp-block-file .wp-block-file__button{border-color:#ff6600;background-color:#ff6600;color:#000000;font-family:inherit;font-weight:500;line-height:1em;font-size:16px;font-size:1rem;padding-top:15px;padding-right:30px;padding-bottom:15px;padding-left:30px;}.ast-single-post .entry-content .wp-block-button .wp-block-button__link,.ast-single-post .entry-content .wp-block-search .wp-block-search__button,body .entry-content .wp-block-file .wp-block-file__button{text-decoration:none;}@media (max-width:921px){.wp-block-button .wp-block-button__link,.wp-block-search .wp-block-search__button,body .wp-block-file .wp-block-file__button{padding-top:14px;padding-right:28px;padding-bottom:14px;padding-left:28px;}}@media (max-width:544px){.wp-block-button .wp-block-button__link,.wp-block-search .wp-block-search__button,body .wp-block-file .wp-block-file__button{padding-top:12px;padding-right:24px;padding-bottom:12px;padding-left:24px;}}.menu-toggle,button,.ast-button,.ast-custom-button,.button,input#submit,input[type="button"],input[type="submit"],input[type="reset"],#comments .submit,.search .search-submit,form[CLASS*="wp-block-search__"].wp-block-search .wp-block-search__inside-wrapper .wp-block-search__button,body .wp-block-file .wp-block-file__button,.search .search-submit{border-style:solid;border-top-width:0;border-right-width:0;border-left-width:0;border-bottom-width:0;color:#000000;border-color:#ff6600;background-color:#ff6600;padding-top:15px;padding-right:30px;padding-bottom:15px;padding-left:30px;font-family:inherit;font-weight:500;font-size:16px;font-size:1rem;line-height:1em;}button:focus,.menu-toggle:hover,button:hover,.ast-button:hover,.ast-custom-button:hover .button:hover,.ast-custom-button:hover ,input[type=reset]:hover,input[type=reset]:focus,input#submit:hover,input#submit:focus,input[type="button"]:hover,input[type="button"]:focus,input[type="submit"]:hover,input[type="submit"]:focus,form[CLASS*="wp-block-search__"].wp-block-search .wp-block-search__inside-wrapper .wp-block-search__button:hover,form[CLASS*="wp-block-search__"].wp-block-search .wp-block-search__inside-wrapper .wp-block-search__button:focus,body .wp-block-file .wp-block-file__button:hover,body .wp-block-file .wp-block-file__button:focus{color:#ffffff;background-color:var(--ast-global-color-1);border-color:var(--ast-global-color-1);}form[CLASS*="wp-block-search__"].wp-block-search .wp-block-search__inside-wrapper .wp-block-search__button.has-icon{padding-top:calc(15px - 3px);padding-right:calc(30px - 3px);padding-bottom:calc(15px - 3px);padding-left:calc(30px - 3px);}@media (max-width:921px){.menu-toggle,button,.ast-button,.ast-custom-button,.button,input#submit,input[type="button"],input[type="submit"],input[type="reset"],#comments .submit,.search .search-submit,form[CLASS*="wp-block-search__"].wp-block-search .wp-block-search__inside-wrapper .wp-block-search__button,body .wp-block-file .wp-block-file__button,.search .search-submit{padding-top:14px;padding-right:28px;padding-bottom:14px;padding-left:28px;}}@media (max-width:544px){.menu-toggle,button,.ast-button,.ast-custom-button,.button,input#submit,input[type="button"],input[type="submit"],input[type="reset"],#comments .submit,.search .search-submit,form[CLASS*="wp-block-search__"].wp-block-search .wp-block-search__inside-wrapper .wp-block-search__button,body .wp-block-file .wp-block-file__button,.search .search-submit{padding-top:12px;padding-right:24px;padding-bottom:12px;padding-left:24px;}}@media (max-width:921px){.ast-mobile-header-stack .main-header-bar .ast-search-menu-icon{display:inline-block;}.ast-header-break-point.ast-header-custom-item-outside .ast-mobile-header-stack .main-header-bar .ast-search-icon{margin:0;}.ast-comment-avatar-wrap img{max-width:2.5em;}.ast-comment-meta{padding:0 1.8888em 1.3333em;}}@media (min-width:544px){.ast-container{max-width:100%;}}@media (max-width:544px){.ast-separate-container .ast-article-post,.ast-separate-container .ast-article-single,.ast-separate-container .comments-title,.ast-separate-container .ast-archive-description{padding:1.5em 1em;}.ast-separate-container #content .ast-container{padding-left:0.54em;padding-right:0.54em;}.ast-separate-container .ast-comment-list .bypostauthor{padding:.5em;}.ast-search-menu-icon.ast-dropdown-active .search-field{width:170px;}} #ast-mobile-header .ast-site-header-cart-li a{pointer-events:none;}.ast-separate-container{background-color:var(--ast-global-color-4);background-image:none;}@media (max-width:921px){.site-title{display:block;}.site-header .site-description{display:none;}h1,.entry-content :where(h1){font-size:30px;}h2,.entry-content :where(h2){font-size:25px;}h3,.entry-content :where(h3){font-size:20px;}}@media (max-width:544px){.site-title{display:block;}.site-header .site-description{display:none;}h1,.entry-content :where(h1){font-size:30px;}h2,.entry-content :where(h2){font-size:25px;}h3,.entry-content :where(h3){font-size:20px;}}@media (max-width:921px){html{font-size:91.2%;}}@media (max-width:544px){html{font-size:91.2%;}}@media (min-width:922px){.ast-container{max-width:1240px;}}@media (min-width:922px){.site-content .ast-container{display:flex;}}@media (max-width:921px){.site-content .ast-container{flex-direction:column;}}.entry-content :where(h1,h2,h3,h4,h5,h6){clear:none;}@media (min-width:922px){.main-header-menu .sub-menu .menu-item.ast-left-align-sub-menu:hover > .sub-menu,.main-header-menu .sub-menu .menu-item.ast-left-align-sub-menu.focus > .sub-menu{margin-left:-0px;}}.entry-content li > p{margin-bottom:0;}.site .comments-area{padding-bottom:2em;margin-top:2em;}.wp-block-file {display: flex;align-items: center;flex-wrap: wrap;justify-content: space-between;}.wp-block-pullquote {border: none;}.wp-block-pullquote blockquote::before {content: "\201D";font-family: "Helvetica",sans-serif;display: flex;transform: rotate( 180deg );font-size: 6rem;font-style: normal;line-height: 1;font-weight: bold;align-items: center;justify-content: center;}.has-text-align-right > blockquote::before {justify-content: flex-start;}.has-text-align-left > blockquote::before {justify-content: flex-end;}figure.wp-block-pullquote.is-style-solid-color blockquote {max-width: 100%;text-align: inherit;}:root {--wp--custom--ast-default-block-top-padding: 3em;--wp--custom--ast-default-block-right-padding: 3em;--wp--custom--ast-default-block-bottom-padding: 3em;--wp--custom--ast-default-block-left-padding: 3em;--wp--custom--ast-container-width: 1200px;--wp--custom--ast-content-width-size: 1200px;--wp--custom--ast-wide-width-size: calc(1200px + var(--wp--custom--ast-default-block-left-padding) + var(--wp--custom--ast-default-block-right-padding));}.ast-narrow-container {--wp--custom--ast-content-width-size: 750px;--wp--custom--ast-wide-width-size: 750px;}@media(max-width: 921px) {:root {--wp--custom--ast-default-block-top-padding: 3em;--wp--custom--ast-default-block-right-padding: 2em;--wp--custom--ast-default-block-bottom-padding: 3em;--wp--custom--ast-default-block-left-padding: 2em;}}@media(max-width: 544px) {:root {--wp--custom--ast-default-block-top-padding: 3em;--wp--custom--ast-default-block-right-padding: 1.5em;--wp--custom--ast-default-block-bottom-padding: 3em;--wp--custom--ast-default-block-left-padding: 1.5em;}}.entry-content > .wp-block-group,.entry-content > .wp-block-cover,.entry-content > .wp-block-columns {padding-top: var(--wp--custom--ast-default-block-top-padding);padding-right: var(--wp--custom--ast-default-block-right-padding);padding-bottom: var(--wp--custom--ast-default-block-bottom-padding);padding-left: var(--wp--custom--ast-default-block-left-padding);}.ast-plain-container.ast-no-sidebar .entry-content > .alignfull,.ast-page-builder-template .ast-no-sidebar .entry-content > .alignfull {margin-left: calc( -50vw + 50%);margin-right: calc( -50vw + 50%);max-width: 100vw;width: 100vw;}.ast-plain-container.ast-no-sidebar .entry-content .alignfull .alignfull,.ast-page-builder-template.ast-no-sidebar .entry-content .alignfull .alignfull,.ast-plain-container.ast-no-sidebar .entry-content .alignfull .alignwide,.ast-page-builder-template.ast-no-sidebar .entry-content .alignfull .alignwide,.ast-plain-container.ast-no-sidebar .entry-content .alignwide .alignfull,.ast-page-builder-template.ast-no-sidebar .entry-content .alignwide .alignfull,.ast-plain-container.ast-no-sidebar .entry-content .alignwide .alignwide,.ast-page-builder-template.ast-no-sidebar .entry-content .alignwide .alignwide,.ast-plain-container.ast-no-sidebar .entry-content .wp-block-column .alignfull,.ast-page-builder-template.ast-no-sidebar .entry-content .wp-block-column .alignfull,.ast-plain-container.ast-no-sidebar .entry-content .wp-block-column .alignwide,.ast-page-builder-template.ast-no-sidebar .entry-content .wp-block-column .alignwide {margin-left: auto;margin-right: auto;width: 100%;}[data-ast-blocks-layout] .wp-block-separator:not(.is-style-dots) {height: 0;}[data-ast-blocks-layout] .wp-block-separator {margin: 20px auto;}[data-ast-blocks-layout] .wp-block-separator:not(.is-style-wide):not(.is-style-dots) {max-width: 100px;}[data-ast-blocks-layout] .wp-block-separator.has-background {padding: 0;}.entry-content[data-ast-blocks-layout] > * {max-width: var(--wp--custom--ast-content-width-size);margin-left: auto;margin-right: auto;}.entry-content[data-ast-blocks-layout] > .alignwide {max-width: var(--wp--custom--ast-wide-width-size);}.entry-content[data-ast-blocks-layout] .alignfull {max-width: none;}.entry-content .wp-block-columns {margin-bottom: 0;}blockquote {margin: 1.5em;border-color: rgba(0,0,0,0.05);}.wp-block-quote:not(.has-text-align-right):not(.has-text-align-center) {border-left: 5px solid rgba(0,0,0,0.05);}.has-text-align-right > blockquote,blockquote.has-text-align-right {border-right: 5px solid rgba(0,0,0,0.05);}.has-text-align-left > blockquote,blockquote.has-text-align-left {border-left: 5px solid rgba(0,0,0,0.05);}.wp-block-site-tagline,.wp-block-latest-posts .read-more {margin-top: 15px;}.wp-block-loginout p label {display: block;}.wp-block-loginout p:not(.login-remember):not(.login-submit) input {width: 100%;}.wp-block-loginout input:focus {border-color: transparent;}.wp-block-loginout input:focus {outline: thin dotted;}.entry-content .wp-block-media-text .wp-block-media-text__content {padding: 0 0 0 8%;}.entry-content .wp-block-media-text.has-media-on-the-right .wp-block-media-text__content {padding: 0 8% 0 0;}.entry-content .wp-block-media-text.has-background .wp-block-media-text__content {padding: 8%;}.entry-content .wp-block-cover:not([class*="background-color"]):not(.has-text-color.has-link-color) .wp-block-cover__inner-container,.entry-content .wp-block-cover:not([class*="background-color"]) .wp-block-cover-image-text,.entry-content .wp-block-cover:not([class*="background-color"]) .wp-block-cover-text,.entry-content .wp-block-cover-image:not([class*="background-color"]) .wp-block-cover__inner-container,.entry-content .wp-block-cover-image:not([class*="background-color"]) .wp-block-cover-image-text,.entry-content .wp-block-cover-image:not([class*="background-color"]) .wp-block-cover-text {color: var(--ast-global-color-primary,var(--ast-global-color-5));}.wp-block-loginout .login-remember input {width: 1.1rem;height: 1.1rem;margin: 0 5px 4px 0;vertical-align: middle;}.wp-block-latest-posts > li > *:first-child,.wp-block-latest-posts:not(.is-grid) > li:first-child {margin-top: 0;}.entry-content > .wp-block-buttons,.entry-content > .wp-block-uagb-buttons {margin-bottom: 1.5em;}.wp-block-search__inside-wrapper .wp-block-search__input {padding: 0 10px;color: var(--ast-global-color-3);background: var(--ast-global-color-primary,var(--ast-global-color-5));border-color: var(--ast-border-color);}.wp-block-latest-posts .read-more {margin-bottom: 1.5em;}.wp-block-search__no-button .wp-block-search__inside-wrapper .wp-block-search__input {padding-top: 5px;padding-bottom: 5px;}.wp-block-latest-posts .wp-block-latest-posts__post-date,.wp-block-latest-posts .wp-block-latest-posts__post-author {font-size: 1rem;}.wp-block-latest-posts > li > *,.wp-block-latest-posts:not(.is-grid) > li {margin-top: 12px;margin-bottom: 12px;}.ast-page-builder-template .entry-content[data-ast-blocks-layout] > .alignwide:where(:not(.uagb-is-root-container):not(.spectra-is-root-container)) > * {max-width: var(--wp--custom--ast-wide-width-size);}.ast-page-builder-template .entry-content[data-ast-blocks-layout] > .inherit-container-width > *,.ast-page-builder-template .entry-content[data-ast-blocks-layout] > *:not(.wp-block-group):where(:not(.uagb-is-root-container):not(.spectra-is-root-container)) > *,.entry-content[data-ast-blocks-layout] > .wp-block-cover .wp-block-cover__inner-container {max-width: none ;margin-left: auto;margin-right: auto;}.ast-page-builder-template .entry-content[data-ast-blocks-layout] > *,.ast-page-builder-template .entry-content[data-ast-blocks-layout] > .alignfull:where(:not(.wp-block-group):not(.uagb-is-root-container):not(.spectra-is-root-container)) > * {max-width: none;}.entry-content[data-ast-blocks-layout] .wp-block-cover:not(.alignleft):not(.alignright) {width: auto;}@media(max-width: 1200px) {.ast-separate-container .entry-content > .alignfull,.ast-separate-container .entry-content[data-ast-blocks-layout] > .alignwide,.ast-plain-container .entry-content[data-ast-blocks-layout] > .alignwide,.ast-plain-container .entry-content .alignfull {margin-left: calc(-1 * min(var(--ast-container-default-xlg-padding),20px)) ;margin-right: calc(-1 * min(var(--ast-container-default-xlg-padding),20px));}}@media(min-width: 1201px) {.ast-separate-container .entry-content > .alignfull {margin-left: calc(-1 * var(--ast-container-default-xlg-padding) );margin-right: calc(-1 * var(--ast-container-default-xlg-padding) );}.ast-separate-container .entry-content[data-ast-blocks-layout] > .alignwide,.ast-plain-container .entry-content[data-ast-blocks-layout] > .alignwide {margin-left: calc(-1 * var(--wp--custom--ast-default-block-left-padding) );margin-right: calc(-1 * var(--wp--custom--ast-default-block-right-padding) );}}@media(min-width: 921px) {.ast-separate-container .entry-content .wp-block-group.alignwide:not(.inherit-container-width) > :where(:not(.alignleft):not(.alignright)),.ast-plain-container .entry-content .wp-block-group.alignwide:not(.inherit-container-width) > :where(:not(.alignleft):not(.alignright)) {max-width: calc( var(--wp--custom--ast-content-width-size) + 80px );}.ast-plain-container.ast-right-sidebar .entry-content[data-ast-blocks-layout] .alignfull,.ast-plain-container.ast-left-sidebar .entry-content[data-ast-blocks-layout] .alignfull {margin-left: -60px;margin-right: -60px;}}@media(min-width: 544px) {.entry-content > .alignleft {margin-right: 20px;}.entry-content > .alignright {margin-left: 20px;}}@media (max-width:544px){.wp-block-columns .wp-block-column:not(:last-child){margin-bottom:20px;}.wp-block-latest-posts{margin:0;}}@media( max-width: 600px ) {.entry-content .wp-block-media-text .wp-block-media-text__content,.entry-content .wp-block-media-text.has-media-on-the-right .wp-block-media-text__content {padding: 8% 0 0;}.entry-content .wp-block-media-text.has-background .wp-block-media-text__content {padding: 8%;}}.ast-page-builder-template .entry-header {padding-left: 0;}.ast-narrow-container .site-content .wp-block-uagb-image--align-full .wp-block-uagb-image__figure {max-width: 100%;margin-left: auto;margin-right: auto;}.entry-content ul,.entry-content ol {padding: revert;margin: revert;padding-left: 20px;}.entry-content ul.wc-block-product-template{padding: 0;}:root .has-ast-global-color-0-color{color:var(--ast-global-color-0);}:root .has-ast-global-color-0-background-color{background-color:var(--ast-global-color-0);}:root .wp-block-button .has-ast-global-color-0-color{color:var(--ast-global-color-0);}:root .wp-block-button .has-ast-global-color-0-background-color{background-color:var(--ast-global-color-0);}:root .has-ast-global-color-1-color{color:var(--ast-global-color-1);}:root .has-ast-global-color-1-background-color{background-color:var(--ast-global-color-1);}:root .wp-block-button .has-ast-global-color-1-color{color:var(--ast-global-color-1);}:root .wp-block-button .has-ast-global-color-1-background-color{background-color:var(--ast-global-color-1);}:root .has-ast-global-color-2-color{color:var(--ast-global-color-2);}:root .has-ast-global-color-2-background-color{background-color:var(--ast-global-color-2);}:root .wp-block-button .has-ast-global-color-2-color{color:var(--ast-global-color-2);}:root .wp-block-button .has-ast-global-color-2-background-color{background-color:var(--ast-global-color-2);}:root .has-ast-global-color-3-color{color:var(--ast-global-color-3);}:root .has-ast-global-color-3-background-color{background-color:var(--ast-global-color-3);}:root .wp-block-button .has-ast-global-color-3-color{color:var(--ast-global-color-3);}:root .wp-block-button .has-ast-global-color-3-background-color{background-color:var(--ast-global-color-3);}:root .has-ast-global-color-4-color{color:var(--ast-global-color-4);}:root .has-ast-global-color-4-background-color{background-color:var(--ast-global-color-4);}:root .wp-block-button .has-ast-global-color-4-color{color:var(--ast-global-color-4);}:root .wp-block-button .has-ast-global-color-4-background-color{background-color:var(--ast-global-color-4);}:root .has-ast-global-color-5-color{color:var(--ast-global-color-5);}:root .has-ast-global-color-5-background-color{background-color:var(--ast-global-color-5);}:root .wp-block-button .has-ast-global-color-5-color{color:var(--ast-global-color-5);}:root .wp-block-button .has-ast-global-color-5-background-color{background-color:var(--ast-global-color-5);}:root .has-ast-global-color-6-color{color:var(--ast-global-color-6);}:root .has-ast-global-color-6-background-color{background-color:var(--ast-global-color-6);}:root .wp-block-button .has-ast-global-color-6-color{color:var(--ast-global-color-6);}:root .wp-block-button .has-ast-global-color-6-background-color{background-color:var(--ast-global-color-6);}:root .has-ast-global-color-7-color{color:var(--ast-global-color-7);}:root .has-ast-global-color-7-background-color{background-color:var(--ast-global-color-7);}:root .wp-block-button .has-ast-global-color-7-color{color:var(--ast-global-color-7);}:root .wp-block-button .has-ast-global-color-7-background-color{background-color:var(--ast-global-color-7);}:root .has-ast-global-color-8-color{color:var(--ast-global-color-8);}:root .has-ast-global-color-8-background-color{background-color:var(--ast-global-color-8);}:root .wp-block-button .has-ast-global-color-8-color{color:var(--ast-global-color-8);}:root .wp-block-button .has-ast-global-color-8-background-color{background-color:var(--ast-global-color-8);}:root{--ast-global-color-0:#046bd2;--ast-global-color-1:#045cb4;--ast-global-color-2:#1e293b;--ast-global-color-3:#334155;--ast-global-color-4:#FFFFFF;--ast-global-color-5:#F0F5FA;--ast-global-color-6:#111111;--ast-global-color-7:#D1D5DB;--ast-global-color-8:#111111;}:root {--ast-border-color : var(--ast-global-color-7);}.ast-single-entry-banner {-js-display: flex;display: flex;flex-direction: column;justify-content: center;text-align: center;position: relative;background: var(--ast-title-layout-bg);}.ast-single-entry-banner[data-banner-layout="layout-1"] {max-width: 1200px;background: inherit;padding: 20px 0;}.ast-single-entry-banner[data-banner-width-type="custom"] {margin: 0 auto;width: 100%;}.ast-single-entry-banner + .site-content .entry-header {margin-bottom: 0;}.site .ast-author-avatar {--ast-author-avatar-size: ;}a.ast-underline-text {text-decoration: underline;}.ast-container > .ast-terms-link {position: relative;display: block;}a.ast-button.ast-badge-tax {padding: 4px 8px;border-radius: 3px;font-size: inherit;}header.entry-header{text-align:left;}header.entry-header .entry-title{font-weight:600;font-size:32px;font-size:2rem;}header.entry-header > *:not(:last-child){margin-bottom:10px;}header.entry-header .post-thumb-img-content{text-align:center;}header.entry-header .post-thumb img,.ast-single-post-featured-section.post-thumb img{aspect-ratio:16/9;width:100%;height:100%;}@media (max-width:921px){header.entry-header{text-align:left;}}@media (max-width:544px){header.entry-header{text-align:left;}}.ast-archive-entry-banner {-js-display: flex;display: flex;flex-direction: column;justify-content: center;text-align: center;position: relative;background: var(--ast-title-layout-bg);}.ast-archive-entry-banner[data-banner-width-type="custom"] {margin: 0 auto;width: 100%;}.ast-archive-entry-banner[data-banner-layout="layout-1"] {background: inherit;padding: 20px 0;text-align: left;}body.archive .ast-archive-description{max-width:1200px;width:100%;text-align:left;padding-top:3em;padding-right:3em;padding-bottom:3em;padding-left:3em;}body.archive .ast-archive-description .ast-archive-title,body.archive .ast-archive-description .ast-archive-title *{font-weight:600;font-size:32px;font-size:2rem;}body.archive .ast-archive-description > *:not(:last-child){margin-bottom:10px;}@media (max-width:921px){body.archive .ast-archive-description{text-align:left;}}@media (max-width:544px){body.archive .ast-archive-description{text-align:left;}}.ast-breadcrumbs .trail-browse,.ast-breadcrumbs .trail-items,.ast-breadcrumbs .trail-items li{display:inline-block;margin:0;padding:0;border:none;background:inherit;text-indent:0;text-decoration:none;}.ast-breadcrumbs .trail-browse{font-size:inherit;font-style:inherit;font-weight:inherit;color:inherit;}.ast-breadcrumbs .trail-items{list-style:none;}.trail-items li::after{padding:0 0.3em;content:"\00bb";}.trail-items li:last-of-type::after{display:none;}h1,h2,h3,h4,h5,h6,.entry-content :where(h1,h2,h3,h4,h5,h6){color:#ff6600;}.entry-title a{color:#ff6600;}@media (max-width:921px){.ast-builder-grid-row-container.ast-builder-grid-row-tablet-3-firstrow .ast-builder-grid-row > *:first-child,.ast-builder-grid-row-container.ast-builder-grid-row-tablet-3-lastrow .ast-builder-grid-row > *:last-child{grid-column:1 / -1;}}@media (max-width:544px){.ast-builder-grid-row-container.ast-builder-grid-row-mobile-3-firstrow .ast-builder-grid-row > *:first-child,.ast-builder-grid-row-container.ast-builder-grid-row-mobile-3-lastrow .ast-builder-grid-row > *:last-child{grid-column:1 / -1;}}.ast-builder-layout-element[data-section="title_tagline"]{display:flex;}@media (max-width:921px){.ast-header-break-point .ast-builder-layout-element[data-section="title_tagline"]{display:flex;}}@media (max-width:544px){.ast-header-break-point .ast-builder-layout-element[data-section="title_tagline"]{display:flex;}}.ast-builder-menu-1{font-family:inherit;font-weight:inherit;}.ast-builder-menu-1 .menu-item > .menu-link{color:var(--ast-global-color-3);}.ast-builder-menu-1 .menu-item > .ast-menu-toggle{color:var(--ast-global-color-3);}.ast-builder-menu-1 .menu-link:hover,.ast-builder-menu-1 .main-header-menu > .menu-item:hover > .menu-link,.ast-builder-menu-1 .inline-on-mobile .ast-menu-toggle:hover,.ast-builder-menu-1 .inline-on-mobile .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-1 .ast-menu-toggle:hover,.ast-builder-menu-1 .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-1 .menu-item.current-menu-item > .menu-link,.ast-builder-menu-1 .inline-on-mobile .menu-item.current-menu-item > .ast-menu-toggle,.ast-builder-menu-1 .current-menu-ancestor > .menu-link{color:var(--ast-global-color-1);}.ast-builder-menu-1 .menu-item.current-menu-item > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-1 .sub-menu,.ast-builder-menu-1 .inline-on-mobile .sub-menu{border-top-width:2px;border-bottom-width:0px;border-right-width:0px;border-left-width:0px;border-color:#ff6600;border-style:solid;}.ast-builder-menu-1 .sub-menu .sub-menu{top:-2px;}.ast-builder-menu-1 .main-header-menu > .menu-item > .sub-menu,.ast-builder-menu-1 .main-header-menu > .menu-item > .astra-full-megamenu-wrapper{margin-top:0px;}.ast-desktop .ast-builder-menu-1 .main-header-menu > .menu-item > .sub-menu:before,.ast-desktop .ast-builder-menu-1 .main-header-menu > .menu-item > .astra-full-megamenu-wrapper:before{height:calc( 0px + 2px + 5px );}.ast-desktop .ast-builder-menu-1 .menu-item .sub-menu .menu-link{border-style:none;}@media (max-width:921px){.ast-header-break-point .ast-builder-menu-1 .menu-item.menu-item-has-children > .ast-menu-toggle{top:0;}.ast-builder-menu-1 .inline-on-mobile .menu-item.menu-item-has-children > .ast-menu-toggle{right:-15px;}.ast-builder-menu-1 .menu-item-has-children > .menu-link:after{content:unset;}.ast-builder-menu-1 .main-header-menu > .menu-item > .sub-menu,.ast-builder-menu-1 .main-header-menu > .menu-item > .astra-full-megamenu-wrapper{margin-top:0;}}@media (max-width:544px){.ast-header-break-point .ast-builder-menu-1 .menu-item.menu-item-has-children > .ast-menu-toggle{top:0;}.ast-builder-menu-1 .main-header-menu > .menu-item > .sub-menu,.ast-builder-menu-1 .main-header-menu > .menu-item > .astra-full-megamenu-wrapper{margin-top:0;}}.ast-builder-menu-1{display:flex;}@media (max-width:921px){.ast-header-break-point .ast-builder-menu-1{display:flex;}}@media (max-width:544px){.ast-header-break-point .ast-builder-menu-1{display:flex;}}.site-below-footer-wrap{padding-top:20px;padding-bottom:20px;}.site-below-footer-wrap[data-section="section-below-footer-builder"]{background-color:var(--ast-global-color-4 );min-height:60px;border-style:solid;border-width:0px;border-top-width:1px;border-top-color:var( --ast-global-color-subtle-background,var(--ast-global-color-7) );}.site-below-footer-wrap[data-section="section-below-footer-builder"] .ast-builder-grid-row{max-width:1200px;min-height:60px;margin-left:auto;margin-right:auto;}.site-below-footer-wrap[data-section="section-below-footer-builder"] .ast-builder-grid-row,.site-below-footer-wrap[data-section="section-below-footer-builder"] .site-footer-section{align-items:center;}.site-below-footer-wrap[data-section="section-below-footer-builder"].ast-footer-row-inline .site-footer-section{display:flex;margin-bottom:0;}.ast-builder-grid-row-full .ast-builder-grid-row{grid-template-columns:1fr;}@media (max-width:921px){.site-below-footer-wrap[data-section="section-below-footer-builder"].ast-footer-row-tablet-inline .site-footer-section{display:flex;margin-bottom:0;}.site-below-footer-wrap[data-section="section-below-footer-builder"].ast-footer-row-tablet-stack .site-footer-section{display:block;margin-bottom:10px;}.ast-builder-grid-row-container.ast-builder-grid-row-tablet-full .ast-builder-grid-row{grid-template-columns:1fr;}}@media (max-width:544px){.site-below-footer-wrap[data-section="section-below-footer-builder"].ast-footer-row-mobile-inline .site-footer-section{display:flex;margin-bottom:0;}.site-below-footer-wrap[data-section="section-below-footer-builder"].ast-footer-row-mobile-stack .site-footer-section{display:block;margin-bottom:10px;}.ast-builder-grid-row-container.ast-builder-grid-row-mobile-full .ast-builder-grid-row{grid-template-columns:1fr;}}.site-below-footer-wrap[data-section="section-below-footer-builder"]{display:grid;}@media (max-width:921px){.ast-header-break-point .site-below-footer-wrap[data-section="section-below-footer-builder"]{display:grid;}}@media (max-width:544px){.ast-header-break-point .site-below-footer-wrap[data-section="section-below-footer-builder"]{display:grid;}}.ast-footer-copyright{text-align:center;}.ast-footer-copyright.site-footer-focus-item {color:var(--ast-global-color-3);}@media (max-width:921px){.ast-footer-copyright{text-align:center;}}@media (max-width:544px){.ast-footer-copyright{text-align:center;}}.ast-footer-copyright.site-footer-focus-item {font-size:16px;font-size:1rem;}.ast-footer-copyright.ast-builder-layout-element{display:flex;}@media (max-width:921px){.ast-header-break-point .ast-footer-copyright.ast-builder-layout-element{display:flex;}}@media (max-width:544px){.ast-header-break-point .ast-footer-copyright.ast-builder-layout-element{display:flex;}}.footer-widget-area.widget-area.site-footer-focus-item{width:auto;}.ast-footer-row-inline .footer-widget-area.widget-area.site-footer-focus-item{width:100%;}.elementor-widget-heading .elementor-heading-title{margin:0;}.elementor-page .ast-menu-toggle{color:unset;background:unset;}.elementor-post.elementor-grid-item.hentry{margin-bottom:0;}.woocommerce div.product .elementor-element.elementor-products-grid .related.products ul.products li.product,.elementor-element .elementor-wc-products .woocommerce[class*='columns-'] ul.products li.product{width:auto;margin:0;float:none;}.elementor-toc__list-wrapper{margin:0;}body .elementor hr{background-color:#ccc;margin:0;}.ast-left-sidebar .elementor-section.elementor-section-stretched,.ast-right-sidebar .elementor-section.elementor-section-stretched{max-width:100%;left:0 !important;}.elementor-posts-container [CLASS*="ast-width-"]{width:100%;}.elementor-template-full-width .ast-container{display:block;}.elementor-screen-only,.screen-reader-text,.screen-reader-text span,.ui-helper-hidden-accessible{top:0 !important;}@media (max-width:544px){.elementor-element .elementor-wc-products .woocommerce[class*="columns-"] ul.products li.product{width:auto;margin:0;}.elementor-element .woocommerce .woocommerce-result-count{float:none;}}.ast-desktop .ast-mega-menu-enabled .ast-builder-menu-1 div:not( .astra-full-megamenu-wrapper) .sub-menu,.ast-builder-menu-1 .inline-on-mobile .sub-menu,.ast-desktop .ast-builder-menu-1 .astra-full-megamenu-wrapper,.ast-desktop .ast-builder-menu-1 .menu-item .sub-menu{box-shadow:0px 4px 10px -2px rgba(0,0,0,0.1);}.ast-desktop .ast-mobile-popup-drawer.active .ast-mobile-popup-inner{max-width:35%;}@media (max-width:921px){.ast-mobile-popup-drawer.active .ast-mobile-popup-inner{max-width:90%;}}@media (max-width:544px){.ast-mobile-popup-drawer.active .ast-mobile-popup-inner{max-width:90%;}}.ast-header-break-point .main-header-bar{border-bottom-width:1px;}@media (min-width:922px){.main-header-bar{border-bottom-width:1px;}}.main-header-menu .menu-item,#astra-footer-menu .menu-item,.main-header-bar .ast-masthead-custom-menu-items{-js-display:flex;display:flex;-webkit-box-pack:center;-webkit-justify-content:center;-moz-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-moz-box-orient:vertical;-moz-box-direction:normal;-ms-flex-direction:column;flex-direction:column;}.main-header-menu > .menu-item > .menu-link,#astra-footer-menu > .menu-item > .menu-link{height:100%;-webkit-box-align:center;-webkit-align-items:center;-moz-box-align:center;-ms-flex-align:center;align-items:center;-js-display:flex;display:flex;}.ast-header-break-point .main-navigation ul .menu-item .menu-link .icon-arrow:first-of-type svg{top:.2em;margin-top:0px;margin-left:0px;width:.65em;transform:translate(0,-2px) rotateZ(270deg);}.ast-mobile-popup-content .ast-submenu-expanded > .ast-menu-toggle{transform:rotateX(180deg);overflow-y:auto;}@media (min-width:922px){.ast-builder-menu .main-navigation > ul > li:last-child a{margin-right:0;}}.ast-separate-container .ast-article-inner{background-color:var(--ast-global-color-4);background-image:none;}@media (max-width:921px){.ast-separate-container .ast-article-inner{background-color:var(--ast-global-color-5);background-image:none;}}@media (max-width:544px){.ast-separate-container .ast-article-inner{background-color:var(--ast-global-color-5);background-image:none;}}.ast-separate-container .ast-article-single:not(.ast-related-post),.ast-separate-container .error-404,.ast-separate-container .no-results,.single.ast-separate-container .site-main .ast-author-meta,.ast-separate-container .related-posts-title-wrapper,.ast-separate-container .comments-count-wrapper,.ast-box-layout.ast-plain-container .site-content,.ast-padded-layout.ast-plain-container .site-content,.ast-separate-container .ast-archive-description,.ast-separate-container .comments-area{background-color:var(--ast-global-color-4);background-image:none;}@media (max-width:921px){.ast-separate-container .ast-article-single:not(.ast-related-post),.ast-separate-container .error-404,.ast-separate-container .no-results,.single.ast-separate-container .site-main .ast-author-meta,.ast-separate-container .related-posts-title-wrapper,.ast-separate-container .comments-count-wrapper,.ast-box-layout.ast-plain-container .site-content,.ast-padded-layout.ast-plain-container .site-content,.ast-separate-container .ast-archive-description{background-color:var(--ast-global-color-5);background-image:none;}}@media (max-width:544px){.ast-separate-container .ast-article-single:not(.ast-related-post),.ast-separate-container .error-404,.ast-separate-container .no-results,.single.ast-separate-container .site-main .ast-author-meta,.ast-separate-container .related-posts-title-wrapper,.ast-separate-container .comments-count-wrapper,.ast-box-layout.ast-plain-container .site-content,.ast-padded-layout.ast-plain-container .site-content,.ast-separate-container .ast-archive-description{background-color:var(--ast-global-color-5);background-image:none;}}.ast-separate-container.ast-two-container #secondary .widget{background-color:var(--ast-global-color-4);background-image:none;}@media (max-width:921px){.ast-separate-container.ast-two-container #secondary .widget{background-color:var(--ast-global-color-5);background-image:none;}}@media (max-width:544px){.ast-separate-container.ast-two-container #secondary .widget{background-color:var(--ast-global-color-5);background-image:none;}}.ast-plain-container,.ast-page-builder-template{background-color:var(--ast-global-color-4);background-image:none;}@media (max-width:921px){.ast-plain-container,.ast-page-builder-template{background-color:var(--ast-global-color-5);background-image:none;}}@media (max-width:544px){.ast-plain-container,.ast-page-builder-template{background-color:var(--ast-global-color-5);background-image:none;}}#ast-scroll-top {display: none;position: fixed;text-align: center;cursor: pointer;z-index: 99;width: 2.1em;height: 2.1em;line-height: 2.1;color: #ffffff;border-radius: 2px;content: "";outline: inherit;}@media (min-width: 769px) {#ast-scroll-top {content: "769";}}#ast-scroll-top .ast-icon.icon-arrow svg {margin-left: 0px;vertical-align: middle;transform: translate(0,-20%) rotate(180deg);width: 1.6em;}.ast-scroll-to-top-right {right: 30px;bottom: 30px;}.ast-scroll-to-top-left {left: 30px;bottom: 30px;}#ast-scroll-top{background-color:#ff6600;font-size:15px;}@media (max-width:921px){#ast-scroll-top .ast-icon.icon-arrow svg{width:1em;}}.ast-mobile-header-content > *,.ast-desktop-header-content > * {padding: 10px 0;height: auto;}.ast-mobile-header-content > *:first-child,.ast-desktop-header-content > *:first-child {padding-top: 10px;}.ast-mobile-header-content > .ast-builder-menu,.ast-desktop-header-content > .ast-builder-menu {padding-top: 0;}.ast-mobile-header-content > *:last-child,.ast-desktop-header-content > *:last-child {padding-bottom: 0;}.ast-mobile-header-content .ast-search-menu-icon.ast-inline-search label,.ast-desktop-header-content .ast-search-menu-icon.ast-inline-search label {width: 100%;}.ast-desktop-header-content .main-header-bar-navigation .ast-submenu-expanded > .ast-menu-toggle::before {transform: rotateX(180deg);}#ast-desktop-header .ast-desktop-header-content,.ast-mobile-header-content .ast-search-icon,.ast-desktop-header-content .ast-search-icon,.ast-mobile-header-wrap .ast-mobile-header-content,.ast-main-header-nav-open.ast-popup-nav-open .ast-mobile-header-wrap .ast-mobile-header-content,.ast-main-header-nav-open.ast-popup-nav-open .ast-desktop-header-content {display: none;}.ast-main-header-nav-open.ast-header-break-point #ast-desktop-header .ast-desktop-header-content,.ast-main-header-nav-open.ast-header-break-point .ast-mobile-header-wrap .ast-mobile-header-content {display: block;}.ast-desktop .ast-desktop-header-content .astra-menu-animation-slide-up > .menu-item > .sub-menu,.ast-desktop .ast-desktop-header-content .astra-menu-animation-slide-up > .menu-item .menu-item > .sub-menu,.ast-desktop .ast-desktop-header-content .astra-menu-animation-slide-down > .menu-item > .sub-menu,.ast-desktop .ast-desktop-header-content .astra-menu-animation-slide-down > .menu-item .menu-item > .sub-menu,.ast-desktop .ast-desktop-header-content .astra-menu-animation-fade > .menu-item > .sub-menu,.ast-desktop .ast-desktop-header-content .astra-menu-animation-fade > .menu-item .menu-item > .sub-menu {opacity: 1;visibility: visible;}.ast-hfb-header.ast-default-menu-enable.ast-header-break-point .ast-mobile-header-wrap .ast-mobile-header-content .main-header-bar-navigation {width: unset;margin: unset;}.ast-mobile-header-content.content-align-flex-end .main-header-bar-navigation .menu-item-has-children > .ast-menu-toggle,.ast-desktop-header-content.content-align-flex-end .main-header-bar-navigation .menu-item-has-children > .ast-menu-toggle {left: calc( 20px - 0.907em);right: auto;}.ast-mobile-header-content .ast-search-menu-icon,.ast-mobile-header-content .ast-search-menu-icon.slide-search,.ast-desktop-header-content .ast-search-menu-icon,.ast-desktop-header-content .ast-search-menu-icon.slide-search {width: 100%;position: relative;display: block;right: auto;transform: none;}.ast-mobile-header-content .ast-search-menu-icon.slide-search .search-form,.ast-mobile-header-content .ast-search-menu-icon .search-form,.ast-desktop-header-content .ast-search-menu-icon.slide-search .search-form,.ast-desktop-header-content .ast-search-menu-icon .search-form {right: 0;visibility: visible;opacity: 1;position: relative;top: auto;transform: none;padding: 0;display: block;overflow: hidden;}.ast-mobile-header-content .ast-search-menu-icon.ast-inline-search .search-field,.ast-mobile-header-content .ast-search-menu-icon .search-field,.ast-desktop-header-content .ast-search-menu-icon.ast-inline-search .search-field,.ast-desktop-header-content .ast-search-menu-icon .search-field {width: 100%;padding-right: 5.5em;}.ast-mobile-header-content .ast-search-menu-icon .search-submit,.ast-desktop-header-content .ast-search-menu-icon .search-submit {display: block;position: absolute;height: 100%;top: 0;right: 0;padding: 0 1em;border-radius: 0;}.ast-hfb-header.ast-default-menu-enable.ast-header-break-point .ast-mobile-header-wrap .ast-mobile-header-content .main-header-bar-navigation ul .sub-menu .menu-link {padding-left: 30px;}.ast-hfb-header.ast-default-menu-enable.ast-header-break-point .ast-mobile-header-wrap .ast-mobile-header-content .main-header-bar-navigation .sub-menu .menu-item .menu-item .menu-link {padding-left: 40px;}.ast-mobile-popup-drawer.active .ast-mobile-popup-inner{background-color:#ffffff;;}.ast-mobile-header-wrap .ast-mobile-header-content,.ast-desktop-header-content{background-color:#ffffff;;}.ast-mobile-popup-content > *,.ast-mobile-header-content > *,.ast-desktop-popup-content > *,.ast-desktop-header-content > *{padding-top:0px;padding-bottom:0px;}.content-align-flex-start .ast-builder-layout-element{justify-content:flex-start;}.content-align-flex-start .main-header-menu{text-align:left;}.ast-desktop-header-content,.ast-mobile-header-content{position:absolute;width:100%;}.ast-mobile-popup-drawer.active .menu-toggle-close{color:#3a3a3a;}.ast-mobile-header-wrap .ast-primary-header-bar,.ast-primary-header-bar .site-primary-header-wrap{min-height:80px;}.ast-desktop:not(:has(.ast-header-sticked)) .ast-primary-header-bar .main-header-menu > .menu-item{line-height:80px;}.ast-header-break-point #masthead .ast-mobile-header-wrap .ast-primary-header-bar,.ast-header-break-point #masthead .ast-mobile-header-wrap .ast-below-header-bar,.ast-header-break-point #masthead .ast-mobile-header-wrap .ast-above-header-bar{padding-left:20px;padding-right:20px;}.ast-header-break-point .ast-primary-header-bar{border-bottom-width:1px;border-bottom-color:var( --ast-global-color-subtle-background,var(--ast-global-color-7) );border-bottom-style:solid;}@media (min-width:922px){.ast-primary-header-bar{border-bottom-width:1px;border-bottom-color:var( --ast-global-color-subtle-background,var(--ast-global-color-7) );border-bottom-style:solid;}}.ast-primary-header-bar{background-color:var( --ast-global-color-primary,var(--ast-global-color-4) );}.ast-primary-header-bar{display:block;}@media (max-width:921px){.ast-header-break-point .ast-primary-header-bar{display:grid;}}@media (max-width:544px){.ast-header-break-point .ast-primary-header-bar{display:grid;}}[data-section="section-header-mobile-trigger"] .ast-button-wrap .ast-mobile-menu-trigger-minimal{color:#ff6600;border:none;background:transparent;}[data-section="section-header-mobile-trigger"] .ast-button-wrap .mobile-menu-toggle-icon .ast-mobile-svg{width:20px;height:20px;fill:#ff6600;}[data-section="section-header-mobile-trigger"] .ast-button-wrap .mobile-menu-wrap .mobile-menu{color:#ff6600;}.ast-builder-menu-mobile .main-navigation .main-header-menu .menu-item > .menu-link{color:var(--ast-global-color-3);}.ast-builder-menu-mobile .main-navigation .main-header-menu .menu-item > .ast-menu-toggle{color:var(--ast-global-color-3);}.ast-builder-menu-mobile .main-navigation .menu-link:hover,.ast-builder-menu-mobile .main-navigation .main-header-menu > .menu-item:hover > .menu-link,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .ast-menu-toggle:hover,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .menu-link:hover,.ast-builder-menu-mobile .main-header-menu > .menu-item:hover > .menu-link,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .ast-menu-toggle:hover,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .main-navigation .ast-menu-toggle:hover,.ast-builder-menu-mobile .main-navigation .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-item > .menu-link,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .menu-item.current-menu-item > .ast-menu-toggle,.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-ancestor > .menu-link,.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-ancestor > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-item > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .main-navigation .menu-item.menu-item-has-children > .ast-menu-toggle{top:0;}.ast-builder-menu-mobile .main-navigation .menu-item-has-children > .menu-link:after{content:unset;}.ast-hfb-header .ast-builder-menu-mobile .main-header-menu,.ast-hfb-header .ast-builder-menu-mobile .main-navigation .menu-item .menu-link,.ast-hfb-header .ast-builder-menu-mobile .main-navigation .menu-item .sub-menu .menu-link{border-style:none;}.ast-builder-menu-mobile .main-navigation .menu-item.menu-item-has-children > .ast-menu-toggle{top:0;}@media (max-width:921px){.ast-builder-menu-mobile .main-navigation .main-header-menu .menu-item > .menu-link{color:var(--ast-global-color-3);}.ast-builder-menu-mobile .main-navigation .main-header-menu .menu-item > .ast-menu-toggle{color:var(--ast-global-color-3);}.ast-builder-menu-mobile .main-navigation .menu-link:hover,.ast-builder-menu-mobile .main-navigation .main-header-menu > .menu-item:hover > .menu-link,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .ast-menu-toggle:hover,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);background:var(--ast-global-color-5);}.ast-builder-menu-mobile .main-navigation .ast-menu-toggle:hover,.ast-builder-menu-mobile .main-navigation .main-header-menu > .menu-item:hover > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-item > .menu-link,.ast-builder-menu-mobile .main-navigation .inline-on-mobile .menu-item.current-menu-item > .ast-menu-toggle,.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-ancestor > .menu-link,.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-ancestor > .ast-menu-toggle{color:var(--ast-global-color-1);background:var(--ast-global-color-5);}.ast-builder-menu-mobile .main-navigation .menu-item.current-menu-item > .ast-menu-toggle{color:var(--ast-global-color-1);}.ast-builder-menu-mobile .main-navigation .menu-item.menu-item-has-children > .ast-menu-toggle{top:0;}.ast-builder-menu-mobile .main-navigation .menu-item-has-children > .menu-link:after{content:unset;}.ast-builder-menu-mobile .main-navigation .main-header-menu ,.ast-builder-menu-mobile .main-navigation .main-header-menu .menu-link,.ast-builder-menu-mobile .main-navigation .main-header-menu .sub-menu{background-color:var(--ast-global-color-4);}}@media (max-width:544px){.ast-builder-menu-mobile .main-navigation .menu-item.menu-item-has-children > .ast-menu-toggle{top:0;}}.ast-builder-menu-mobile .main-navigation{display:block;}@media (max-width:921px){.ast-header-break-point .ast-builder-menu-mobile .main-navigation{display:block;}}@media (max-width:544px){.ast-header-break-point .ast-builder-menu-mobile .main-navigation{display:block;}}:root{--e-global-color-astglobalcolor0:#046bd2;--e-global-color-astglobalcolor1:#045cb4;--e-global-color-astglobalcolor2:#1e293b;--e-global-color-astglobalcolor3:#334155;--e-global-color-astglobalcolor4:#FFFFFF;--e-global-color-astglobalcolor5:#F0F5FA;--e-global-color-astglobalcolor6:#111111;--e-global-color-astglobalcolor7:#D1D5DB;--e-global-color-astglobalcolor8:#111111;}
/*# sourceURL=astra-theme-css-inline-css */
</style>
<link rel='stylesheet' id='astra-google-fonts-css' href='https://fonts.googleapis.com/css?family=Ubuntu%3A400%2C&#038;display=swap&#038;ver=4.13.3' media='all' />
<style id='wp-emoji-styles-inline-css'>

	img.wp-smiley, img.emoji {
		display: inline !important;
		border: none !important;
		box-shadow: none !important;
		height: 1em !important;
		width: 1em !important;
		margin: 0 0.07em !important;
		vertical-align: -0.1em !important;
		background: none !important;
		padding: 0 !important;
	}
/*# sourceURL=wp-emoji-styles-inline-css */
</style>
<style id='kevinbatdorf-code-block-pro-style-inline-css'>
.wp-block-kevinbatdorf-code-block-pro{direction:ltr!important;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;-webkit-text-size-adjust:100%!important;box-sizing:border-box!important;position:relative!important}.wp-block-kevinbatdorf-code-block-pro *{box-sizing:border-box!important}.wp-block-kevinbatdorf-code-block-pro pre,.wp-block-kevinbatdorf-code-block-pro pre *{font-size:inherit!important;line-height:inherit!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor) pre{background-image:none!important;border:0!important;border-radius:0!important;border-style:none!important;border-width:0!important;color:inherit!important;font-family:inherit!important;margin:0!important;overflow:auto!important;overflow-wrap:normal!important;padding:16px 0 16px 16px!important;text-align:left!important;white-space:pre!important;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important;outline:2px solid transparent!important;outline-offset:2px!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor) pre:focus-visible{outline-color:inherit!important}.wp-block-kevinbatdorf-code-block-pro.padding-disabled:not(.code-block-pro-editor)
	pre{padding:0!important}.wp-block-kevinbatdorf-code-block-pro.padding-bottom-disabled pre{padding-bottom:0!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor) pre code{background:none!important;background-color:transparent!important;border:0!important;border-radius:0!important;border-style:none!important;border-width:0!important;color:inherit!important;display:block!important;font-family:inherit!important;margin:0!important;overflow-wrap:normal!important;padding:0!important;text-align:left!important;white-space:pre!important;width:100%!important;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor)
	pre
	code
	.line{display:inline-block!important;min-width:var(--cbp-block-width,100%)!important;vertical-align:top!important}.wp-block-kevinbatdorf-code-block-pro.cbp-has-line-numbers:not(.code-block-pro-editor)
	pre
	code
	.line{padding-left:calc(12px + var(--cbp-line-number-width, auto))!important}.wp-block-kevinbatdorf-code-block-pro.cbp-has-line-numbers:not(.code-block-pro-editor)
	pre
	code{counter-increment:step calc(var(--cbp-line-number-start, 1) - 1)!important;counter-reset:step!important}.wp-block-kevinbatdorf-code-block-pro pre code .line{position:relative!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor)
	pre
	code
	.line:before{content:""!important;display:inline-block!important}.wp-block-kevinbatdorf-code-block-pro.cbp-has-line-numbers:not(.code-block-pro-editor)
	pre
	code
	.line:not(.cbp-line-number-disabled):before{color:var(--cbp-line-number-color,#999)!important;content:counter(step)!important;counter-increment:step!important;left:0!important;opacity:.5!important;position:absolute!important;text-align:right!important;transition-duration:.5s!important;transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;-webkit-user-select:none!important;-moz-user-select:none!important;user-select:none!important;width:var(--cbp-line-number-width,auto)!important}.wp-block-kevinbatdorf-code-block-pro.cbp-highlight-hover .line{min-height:var(--cbp-block-height,100%)!important}.wp-block-kevinbatdorf-code-block-pro .line.cbp-line-highlight .cbp-line-highlighter,.wp-block-kevinbatdorf-code-block-pro .line.cbp-no-blur:hover .cbp-line-highlighter,.wp-block-kevinbatdorf-code-block-pro.cbp-highlight-hover:not(.cbp-blur-enabled:not(.cbp-unblur-on-hover))
		.line:hover .cbp-line-highlighter{background:var(--cbp-line-highlight-color,rgba(14,165,233,.2))!important;left:-16px!important;min-height:var(--cbp-block-height,100%)!important;min-width:calc(var(--cbp-block-width, 100%) + 16px)!important;pointer-events:none!important;position:absolute!important;top:0!important;width:100%!important}[data-code-block-pro-font-family="Code-Pro-Comic-Mono.ttf"].wp-block-kevinbatdorf-code-block-pro .line.cbp-line-highlight .cbp-line-highlighter,[data-code-block-pro-font-family="Code-Pro-Comic-Mono.ttf"].wp-block-kevinbatdorf-code-block-pro .line.cbp-no-blur:hover .cbp-line-highlighter,[data-code-block-pro-font-family="Code-Pro-Comic-Mono.ttf"].wp-block-kevinbatdorf-code-block-pro.cbp-highlight-hover:not(.cbp-blur-enabled:not(.cbp-unblur-on-hover))
		.line:hover .cbp-line-highlighter{top:-.125rem!important}[data-code-block-pro-font-family=Code-Pro-Fira-Code].wp-block-kevinbatdorf-code-block-pro .line.cbp-line-highlight .cbp-line-highlighter,[data-code-block-pro-font-family=Code-Pro-Fira-Code].wp-block-kevinbatdorf-code-block-pro .line.cbp-no-blur:hover .cbp-line-highlighter,[data-code-block-pro-font-family=Code-Pro-Fira-Code].wp-block-kevinbatdorf-code-block-pro.cbp-highlight-hover:not(.cbp-blur-enabled:not(.cbp-unblur-on-hover))
		.line:hover .cbp-line-highlighter{top:-1.5px!important}[data-code-block-pro-font-family="Code-Pro-Deja-Vu-Mono.ttf"].wp-block-kevinbatdorf-code-block-pro .line.cbp-line-highlight .cbp-line-highlighter,[data-code-block-pro-font-family="Code-Pro-Deja-Vu-Mono.ttf"].wp-block-kevinbatdorf-code-block-pro .line.cbp-no-blur:hover .cbp-line-highlighter,[data-code-block-pro-font-family="Code-Pro-Deja-Vu-Mono.ttf"].wp-block-kevinbatdorf-code-block-pro.cbp-highlight-hover:not(.cbp-blur-enabled:not(.cbp-unblur-on-hover))
		.line:hover .cbp-line-highlighter,[data-code-block-pro-font-family=Code-Pro-Cozette].wp-block-kevinbatdorf-code-block-pro .line.cbp-line-highlight .cbp-line-highlighter,[data-code-block-pro-font-family=Code-Pro-Cozette].wp-block-kevinbatdorf-code-block-pro .line.cbp-no-blur:hover .cbp-line-highlighter,[data-code-block-pro-font-family=Code-Pro-Cozette].wp-block-kevinbatdorf-code-block-pro.cbp-highlight-hover:not(.cbp-blur-enabled:not(.cbp-unblur-on-hover))
		.line:hover .cbp-line-highlighter{top:-1px!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor).padding-disabled pre
	.line.cbp-line-highlight:after{left:0!important;width:100%!important}.wp-block-kevinbatdorf-code-block-pro.cbp-blur-enabled
	pre
	.line:not(.cbp-no-blur){filter:blur(1.35px)!important;opacity:.8!important;pointer-events:none!important;transition-duration:.2s!important;transition-property:all!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important}.wp-block-kevinbatdorf-code-block-pro.cbp-blur-enabled.cbp-unblur-on-hover:hover
	pre
	.line:not(.cbp-no-blur){opacity:1!important;pointer-events:auto!important;--tw-blur: ;filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)!important}.wp-block-kevinbatdorf-code-block-pro:not(.code-block-pro-editor) pre *{font-family:inherit!important}.cbp-see-more-simple-btn-hover{transition-property:none!important}.cbp-see-more-simple-btn-hover:hover{box-shadow:inset 0 0 100px 100px hsla(0,0%,100%,.1)!important}.code-block-pro-copy-button{border:0!important;border-style:none!important;border-width:0!important;cursor:pointer!important;left:auto!important;line-height:1!important;opacity:.1!important;outline:2px solid transparent!important;outline-offset:2px!important;padding:6px!important;position:absolute!important;right:0!important;top:0!important;transition-duration:.2s!important;transition-property:opacity!important;transition-timing-function:cubic-bezier(.4,0,.2,1)!important;z-index:10!important}.code-block-pro-copy-button:focus{opacity:.4!important}.code-block-pro-copy-button:focus-visible{outline-color:inherit!important}.code-block-pro-copy-button:not([data-has-text-button]){background:none!important;background-color:transparent!important}body
	.wp-block-kevinbatdorf-code-block-pro:not(#x)
	.code-block-pro-copy-button-textarea,body .wp-block-kevinbatdorf-code-block-pro:not(#x)
	.code-block-pro-copy-button-pre{clip:rect(0,0,0,0)!important;background-color:transparent!important;border-width:0!important;color:transparent!important;height:1px!important;left:0!important;margin:-.25rem!important;opacity:0!important;overflow:hidden!important;pointer-events:none!important;position:absolute!important;resize:none!important;top:0!important;white-space:nowrap!important;width:1px!important;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)!important}.wp-block-kevinbatdorf-code-block-pro.padding-disabled
	.code-block-pro-copy-button{padding:0!important}.wp-block-kevinbatdorf-code-block-pro:hover .code-block-pro-copy-button{opacity:.5!important}.wp-block-kevinbatdorf-code-block-pro .code-block-pro-copy-button:hover{opacity:.9!important}.code-block-pro-copy-button[data-has-text-button],.wp-block-kevinbatdorf-code-block-pro:hover
	.code-block-pro-copy-button[data-has-text-button]{opacity:1!important}.wp-block-kevinbatdorf-code-block-pro
	.code-block-pro-copy-button[data-has-text-button]:hover{opacity:.8!important}.code-block-pro-copy-button[data-has-text-button]{border-radius:.75rem!important;display:block!important;margin-right:.75rem!important;margin-top:.7rem!important;padding:.125rem .375rem!important}.code-block-pro-copy-button[data-inside-header-type=headlightsMuted],.code-block-pro-copy-button[data-inside-header-type^=headlights]{margin-top:.85rem!important}.code-block-pro-copy-button[data-inside-header-type=headlightsMutedAlt]{margin-top:.65rem!important}.code-block-pro-copy-button[data-inside-header-type=simpleString]{margin-top:.645rem!important}.code-block-pro-copy-button[data-inside-header-type=pillString]{margin-top:1rem!important}.code-block-pro-copy-button[data-inside-header-type=pillString]
	.cbp-btn-text{position:relative!important;top:1px!important}.cbp-btn-text{font-size:.75rem!important;line-height:1rem!important}.code-block-pro-copy-button .without-check{display:block!important}.code-block-pro-copy-button .with-check{display:none!important}.code-block-pro-copy-button.cbp-copying{opacity:1!important}.code-block-pro-copy-button.cbp-copying .without-check{display:none!important}.code-block-pro-copy-button.cbp-copying .with-check{display:block!important}.cbp-footer-link:hover{text-decoration-line:underline!important}@media print{.wp-block-kevinbatdorf-code-block-pro pre{max-height:none!important}.wp-block-kevinbatdorf-code-block-pro:not(#x) .line:before{background-color:transparent!important;color:inherit!important}.wp-block-kevinbatdorf-code-block-pro:not(#x) .cbp-line-highlighter,.wp-block-kevinbatdorf-code-block-pro:not(#x)>span{display:none!important}}

/*# sourceURL=https://oriolrius.cat/wp-content/plugins/code-block-pro/build/style-index.css */
</style>
<style id='global-styles-inline-css'>
:root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--color--ast-global-color-0: var(--ast-global-color-0);--wp--preset--color--ast-global-color-1: var(--ast-global-color-1);--wp--preset--color--ast-global-color-2: var(--ast-global-color-2);--wp--preset--color--ast-global-color-3: var(--ast-global-color-3);--wp--preset--color--ast-global-color-4: var(--ast-global-color-4);--wp--preset--color--ast-global-color-5: var(--ast-global-color-5);--wp--preset--color--ast-global-color-6: var(--ast-global-color-6);--wp--preset--color--ast-global-color-7: var(--ast-global-color-7);--wp--preset--color--ast-global-color-8: var(--ast-global-color-8);--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgb(252,185,0) 0%,rgb(255,105,0) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgb(255,105,0) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: 13px;--wp--preset--font-size--medium: 20px;--wp--preset--font-size--large: 36px;--wp--preset--font-size--x-large: 42px;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgb(255, 255, 255), 6px 6px rgb(0, 0, 0);--wp--preset--shadow--crisp: 6px 6px 0px rgb(0, 0, 0);}:root { --wp--style--global--content-size: var(--wp--custom--ast-content-width-size);--wp--style--global--wide-size: var(--wp--custom--ast-wide-width-size); }:where(body) { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 24px; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 24px; }:root :where(.is-layout-flow) > :first-child{margin-block-start: 0;}:root :where(.is-layout-flow) > :last-child{margin-block-end: 0;}:root :where(.is-layout-flow) > *{margin-block-start: 24px;margin-block-end: 0;}:root :where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:root :where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:root :where(.is-layout-constrained) > *{margin-block-start: 24px;margin-block-end: 0;}:root :where(.is-layout-flex){gap: 24px;}:root :where(.is-layout-grid){gap: 24px;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}body{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}a:where(:not(.wp-element-button)){text-decoration: none;}:root :where(.wp-element-button, .wp-block-button__link){background-color: #32373c;border-width: 0;color: #fff;font-family: inherit;font-size: inherit;font-style: inherit;font-weight: inherit;letter-spacing: inherit;line-height: inherit;padding-top: calc(0.667em + 2px);padding-right: calc(1.333em + 2px);padding-bottom: calc(0.667em + 2px);padding-left: calc(1.333em + 2px);text-decoration: none;text-transform: inherit;}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-ast-global-color-0-color{color: var(--wp--preset--color--ast-global-color-0) !important;}.has-ast-global-color-1-color{color: var(--wp--preset--color--ast-global-color-1) !important;}.has-ast-global-color-2-color{color: var(--wp--preset--color--ast-global-color-2) !important;}.has-ast-global-color-3-color{color: var(--wp--preset--color--ast-global-color-3) !important;}.has-ast-global-color-4-color{color: var(--wp--preset--color--ast-global-color-4) !important;}.has-ast-global-color-5-color{color: var(--wp--preset--color--ast-global-color-5) !important;}.has-ast-global-color-6-color{color: var(--wp--preset--color--ast-global-color-6) !important;}.has-ast-global-color-7-color{color: var(--wp--preset--color--ast-global-color-7) !important;}.has-ast-global-color-8-color{color: var(--wp--preset--color--ast-global-color-8) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-ast-global-color-0-background-color{background-color: var(--wp--preset--color--ast-global-color-0) !important;}.has-ast-global-color-1-background-color{background-color: var(--wp--preset--color--ast-global-color-1) !important;}.has-ast-global-color-2-background-color{background-color: var(--wp--preset--color--ast-global-color-2) !important;}.has-ast-global-color-3-background-color{background-color: var(--wp--preset--color--ast-global-color-3) !important;}.has-ast-global-color-4-background-color{background-color: var(--wp--preset--color--ast-global-color-4) !important;}.has-ast-global-color-5-background-color{background-color: var(--wp--preset--color--ast-global-color-5) !important;}.has-ast-global-color-6-background-color{background-color: var(--wp--preset--color--ast-global-color-6) !important;}.has-ast-global-color-7-background-color{background-color: var(--wp--preset--color--ast-global-color-7) !important;}.has-ast-global-color-8-background-color{background-color: var(--wp--preset--color--ast-global-color-8) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-ast-global-color-0-border-color{border-color: var(--wp--preset--color--ast-global-color-0) !important;}.has-ast-global-color-1-border-color{border-color: var(--wp--preset--color--ast-global-color-1) !important;}.has-ast-global-color-2-border-color{border-color: var(--wp--preset--color--ast-global-color-2) !important;}.has-ast-global-color-3-border-color{border-color: var(--wp--preset--color--ast-global-color-3) !important;}.has-ast-global-color-4-border-color{border-color: var(--wp--preset--color--ast-global-color-4) !important;}.has-ast-global-color-5-border-color{border-color: var(--wp--preset--color--ast-global-color-5) !important;}.has-ast-global-color-6-border-color{border-color: var(--wp--preset--color--ast-global-color-6) !important;}.has-ast-global-color-7-border-color{border-color: var(--wp--preset--color--ast-global-color-7) !important;}.has-ast-global-color-8-border-color{border-color: var(--wp--preset--color--ast-global-color-8) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}
:root :where(.wp-block-pullquote){font-size: 1.5em;line-height: 1.6;}
/*# sourceURL=global-styles-inline-css */
</style>
<link rel='stylesheet' id='astra-addon-css-css' href='https://oriolrius.cat/wp-content/uploads/astra-addon/astra-addon-6a1d6d359a0761-74043489.css?ver=4.13.3' media='all' />
<link rel='stylesheet' id='elementor-frontend-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/css/frontend.min.css?ver=4.1.1' media='all' />
<link rel='stylesheet' id='widget-heading-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/css/widget-heading.min.css?ver=4.1.1' media='all' />
<link rel='stylesheet' id='widget-nav-menu-css' href='https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/css/widget-nav-menu.min.css?ver=4.1.0' media='all' />
<link rel='stylesheet' id='widget-search-form-css' href='https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/css/widget-search-form.min.css?ver=4.1.0' media='all' />
<link rel='stylesheet' id='elementor-icons-shared-0-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/lib/font-awesome/css/fontawesome.min.css?ver=5.15.3' media='all' />
<link rel='stylesheet' id='elementor-icons-fa-solid-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/lib/font-awesome/css/solid.min.css?ver=5.15.3' media='all' />
<link rel='stylesheet' id='widget-social-icons-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/css/widget-social-icons.min.css?ver=4.1.1' media='all' />
<link rel='stylesheet' id='e-apple-webkit-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/css/conditionals/apple-webkit.min.css?ver=4.1.1' media='all' />
<link rel='stylesheet' id='widget-image-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/css/widget-image.min.css?ver=4.1.1' media='all' />
<link rel='stylesheet' id='elementor-icons-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/lib/eicons/css/elementor-icons.min.css?ver=5.49.0' media='all' />
<link rel='stylesheet' id='elementor-post-9604-css' href='https://oriolrius.cat/wp-content/uploads/elementor/css/post-9604.css?ver=1780313622' media='all' />
<link rel='stylesheet' id='widget-posts-css' href='https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/css/widget-posts.min.css?ver=4.1.0' media='all' />
<link rel='stylesheet' id='elementor-post-9608-css' href='https://oriolrius.cat/wp-content/uploads/elementor/css/post-9608.css?ver=1780313622' media='all' />
<link rel='stylesheet' id='elementor-post-9613-css' href='https://oriolrius.cat/wp-content/uploads/elementor/css/post-9613.css?ver=1780313622' media='all' />
<link rel='stylesheet' id='elementor-post-9624-css' href='https://oriolrius.cat/wp-content/uploads/elementor/css/post-9624.css?ver=1780313622' media='all' />
<link rel='stylesheet' id='eael-general-css' href='https://oriolrius.cat/wp-content/plugins/essential-addons-for-elementor-lite/assets/front-end/css/view/general.min.css?ver=6.6.5' media='all' />
<link rel='stylesheet' id='elementor-gf-local-robotomono-css' href='https://oriolrius.cat/wp-content/uploads/elementor/google-fonts/css/robotomono.css?ver=1742472995' media='all' />
<link rel='stylesheet' id='elementor-gf-local-inconsolata-css' href='https://oriolrius.cat/wp-content/uploads/elementor/google-fonts/css/inconsolata.css?ver=1742472996' media='all' />
<link rel='stylesheet' id='elementor-icons-fa-brands-css' href='https://oriolrius.cat/wp-content/plugins/elementor/assets/lib/font-awesome/css/brands.min.css?ver=5.15.3' media='all' />
<script src="https://oriolrius.cat/wp-includes/js/jquery/jquery.min.js?ver=3.7.1" id="jquery-core-js"></script>
<script src="https://oriolrius.cat/wp-includes/js/jquery/jquery-migrate.min.js?ver=3.4.1" id="jquery-migrate-js"></script>
<link rel="https://api.w.org/" href="https://oriolrius.cat/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://oriolrius.cat/wp-json/wp/v2/pages/9608" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://oriolrius.cat/xmlrpc.php?rsd" />
<meta name="generator" content="WordPress 6.9.4" />
<link rel="canonical" href="https://oriolrius.cat/" />
<link rel='shortlink' href='https://oriolrius.cat/' />
<meta name="generator" content="Elementor 4.1.1; features: additional_custom_breakpoints; settings: css_print_method-external, google_font-enabled, font_display-swap">
			<style>
				.e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload),
				.e-con.e-parent:nth-of-type(n+4):not(.e-lazyloaded):not(.e-no-lazyload) * {
					background-image: none !important;
				}
				@media screen and (max-height: 1024px) {
					.e-con.e-parent:nth-of-type(n+3):not(.e-lazyloaded):not(.e-no-lazyload),
					.e-con.e-parent:nth-of-type(n+3):not(.e-lazyloaded):not(.e-no-lazyload) * {
						background-image: none !important;
					}
				}
				@media screen and (max-height: 640px) {
					.e-con.e-parent:nth-of-type(n+2):not(.e-lazyloaded):not(.e-no-lazyload),
					.e-con.e-parent:nth-of-type(n+2):not(.e-lazyloaded):not(.e-no-lazyload) * {
						background-image: none !important;
					}
				}
			</style>
					<style id="wp-custom-css">
			/* Encabezado */
.header {
    background-color: #ffffff;
    color: #4a4a4a;
}


/* Títulos */
h1, h2, h3, h4, h5, h6 {
    color: #FF6600;
    font-family: 'Ubuntu', sans-serif;
}


/* Enlaces */
a {
    color: #FF6600;
}


/* Botón de búsqueda */
button.search-submit {
    background-color: #6200EE;
    color: #ffffff;
}


/* Ocultar título de la página */
.page-title {
    display: none;
}


/* Fondo global */
html, body {
    background-color: #ffffff; /* Fondo blanco */
    margin: 0;
    padding: 0;
}


/* Asegura que los contenedores también sean blancos */
.container, .site-content, .main-content {
    background-color: #ffffff;
}


/* Elimina fondos no deseados de secciones específicas */
.elementor-section, .elementor-column, .elementor-widget {
    background-color: transparent;
}


/* Ajustar la imagen de fondo */
.elementor-section {
    background-size: cover;
    background-position: center center;
}


/* Ajustar el tamaño del texto */
h1, h2, h3, h4, h5, h6 {
    font-family: 'Ubuntu', sans-serif;
    color: #FF6600;
}

p {
    font-family: 'Ubuntu', sans-serif;
    color: #4a4a4a;
}


/* Ajustar el color de los enlaces */
a {
    color: #FF6600;
}

button.search-submit {
    background-color: #6200EE;
    color: #ffffff;
}


/* Ajustar el espaciado entre header y body */
.elementor-section:first-of-type {
    margin-top: 30px; /* Ajusta según sea necesario */
}


/* Asegurar que el header no ocupe demasiado espacio */
.elementor-header {
    padding-bottom: 0;
    margin-bottom: 0;
}




/* Ocultar imagen no deseada */
img[src*="screenshot-oriolrius.cat-2023.04.25-16_04_26.png"] {
    display: none;
}


/*Paginación*/
.nav-links {
    text-align: center; /* Centrar la paginación */
    margin: 20px 0; /* Añadir margen para separarlo del contenido */
}

a.page-numbers, span.page-numbers {
    display: inline-block;
    padding: 10px 15px;
    margin: 5px;
    background-color: #FF6600; /* Fondo naranja para los enlaces */
    color: #fff; /* Texto blanco */
    text-decoration: none;
    border-radius: 4px;
    font-size: 18px; /* 
                      * 
                      * Aumentar el tamaño de la fuente */
    border: 2px solid #FF6600; /* Borde naranja */
    transition: background-color 0.3s ease, color 0.3s ease; /* Transiciones suaves */
}

a.page-numbers:hover, span.page-numbers.current {
    background-color: #fff; /* Fondo blanco */
    color: #FF6600 !important; /* Texto naranja */
    border: 2px solid #FF6600; /* Borde naranja */
    font-weight: bold; /* Negrita para énfasis */
}

/* Normalizar el estilo de todo el texto */
body, p, ul, ol, li {
    font-family: 'Ubuntu', sans-serif; /* Cambiar al tipo de letra deseado */
    font-size: 16px; /* Ajustar al tamaño estándar de tu contenido */
    color: #4a4a4a; /* Color uniforme para todo el texto */
    font-weight: 400; /* Asegurar que el peso sea uniforme */
    line-height: 1.6; /* Espaciado entre líneas para mejor legibilidad */
}


/* Asegurar el estilo uniforme en las listas */
ul, ol {
    margin-left: 20px; /* Indentación para listas */
    padding-left: 20px;
}

li {
    list-style-type: disc; /* Si quieres que las viñetas sean uniformes */
}


/* Ajustar los bloques de código para que sigan el estilo */
code, pre {
    font-family: 'Ubuntu', sans-serif; /* Cambiar al tipo de letra del texto */
    font-size: 16px; /* Igual al texto estándar */
    color: #4a4a4a; /* Mismo color que el texto */
    font-weight: 400; /* Uniformidad en el peso */
    background-color: #f5f5f5; /* Opcional: fondo para bloques de código */
    padding: 5px;
    border-radius: 4px; /* Opcional: bordes redondeados */
    border: 1px solid #ddd; /* Opcional: borde ligero */
}



h1 {
    color: #FF6600 !important;
    font-family: 'Ubuntu', sans-serif !important;
    display: block !important;
}







		</style>
		</head>

<body itemtype='https://schema.org/WebPage' itemscope='itemscope' class="home wp-singular page-template-default page page-id-9608 wp-embed-responsive wp-theme-astra ast-desktop ast-page-builder-template ast-no-sidebar astra-4.13.3 ast-single-post ast-inherit-site-logo-transparent ast-hfb-header elementor-default elementor-kit-9604 elementor-page elementor-page-9608 astra-addon-4.13.3">
			<script>
			(function(){var w=document.documentElement.clientWidth;if(w>0&&w<=921){document.body.classList.add('ast-header-break-point');document.body.classList.remove('ast-desktop');}})();
			</script>
			
<a
	class="skip-link screen-reader-text"
	href="#content">
		Skip to content</a>

<div
class="hfeed site" id="page">
			<header data-elementor-type="header" data-elementor-id="9613" class="elementor elementor-9613 elementor-location-header" data-elementor-post-type="elementor_library">
					<header data-particle_enable="false" data-particle-mobile-disabled="false" class="elementor-section elementor-top-section elementor-element elementor-element-2386e67e elementor-section-full_width elementor-section-content-middle elementor-section-height-default elementor-section-height-default" data-id="2386e67e" data-element_type="section" data-e-type="section" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}">
						<div class="elementor-container elementor-column-gap-default">
					<div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-5fe3e4c" data-id="5fe3e4c" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<div class="elementor-element elementor-element-3dc6a37f elementor-widget elementor-widget-heading" data-id="3dc6a37f" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
					<h2 class="elementor-heading-title elementor-size-default"><a href="https://oriolrius.cat">oriolrius.cat</a></h2>				</div>
				</div>
				<div class="elementor-element elementor-element-86b2319 elementor-widget elementor-widget-text-editor" data-id="86b2319" data-element_type="widget" data-e-type="widget" data-widget_type="text-editor.default">
				<div class="elementor-widget-container">
									<p>Des del 2000 compartiendo sobre&#8230;</p>								</div>
				</div>
				<div class="elementor-element elementor-element-a99337d elementor-nav-menu__align-center elementor-nav-menu--dropdown-tablet elementor-nav-menu__text-align-aside elementor-nav-menu--toggle elementor-nav-menu--burger elementor-widget elementor-widget-nav-menu" data-id="a99337d" data-element_type="widget" data-e-type="widget" data-settings="{&quot;layout&quot;:&quot;horizontal&quot;,&quot;submenu_icon&quot;:{&quot;value&quot;:&quot;&lt;i class=\&quot;fas fa-caret-down\&quot; aria-hidden=\&quot;true\&quot;&gt;&lt;\/i&gt;&quot;,&quot;library&quot;:&quot;fa-solid&quot;},&quot;toggle&quot;:&quot;burger&quot;}" data-widget_type="nav-menu.default">
				<div class="elementor-widget-container">
								<nav aria-label="Menu" class="elementor-nav-menu--main elementor-nav-menu__container elementor-nav-menu--layout-horizontal e--pointer-none">
				<ul id="menu-1-a99337d" class="elementor-nav-menu"><li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-9718"><a aria-expanded="false" href="https://oriolrius.cat/category/tech-2-ca/" class="elementor-item menu-link">Technology<span role="button" class="dropdown-menu-toggle ast-header-navigation-arrow" tabindex="0" aria-expanded="false" aria-label="Menu Toggle" aria-haspopup="true"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span></span></a>
<ul class="sub-menu elementor-nav-menu--dropdown">
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10535"><a href="https://oriolrius.cat/category/office-tech-2-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>BPM, ERP, CRM and other office applications</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10536"><a href="https://oriolrius.cat/category/programming-tech-2-ca-2/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Development, Models and Methodologies</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10537"><a href="https://oriolrius.cat/category/diy-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Domotics, Electronics and DIY projects</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10538"><a href="https://oriolrius.cat/category/multimedia-tech-2-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Multimedia, Gadgets, Mobile phones and Tablets</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10539"><a href="https://oriolrius.cat/category/networking-tech-2-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Networking and Internet</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10540"><a href="https://oriolrius.cat/category/sysadmin-tech-2-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>System administration, Databases, Messaging and Security</a></li>
</ul>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-9716"><a aria-expanded="false" href="https://oriolrius.cat/category/cp-ca/" class="elementor-item menu-link">Crecimiento personal<span role="button" class="dropdown-menu-toggle ast-header-navigation-arrow" tabindex="0" aria-expanded="false" aria-label="Menu Toggle" aria-haspopup="true"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span></span></a>
<ul class="sub-menu elementor-nav-menu--dropdown">
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10528"><a href="https://oriolrius.cat/category/cp-ca/coaching-cp-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Business coaching</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10529"><a href="https://oriolrius.cat/category/cp-ca/ciencia-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Ciencia y sociedad</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10530"><a href="https://oriolrius.cat/category/cp-ca/mindfulness-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Conciencia Plena</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10531"><a href="https://oriolrius.cat/category/cp-ca/branding-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Personal Branding</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10532"><a href="https://oriolrius.cat/category/cp-ca/pnl-cp-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>PNL</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10533"><a href="https://oriolrius.cat/category/cp-ca/gtd-cp-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Productividad Personal</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10534"><a href="https://oriolrius.cat/category/cp-ca/salud-alimentacion-ca/" class="elementor-sub-item menu-link"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Salud y alimentación</a></li>
</ul>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-9717"><a href="https://oriolrius.cat/category/mussol-ca/" class="elementor-item menu-link">Mussol</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11222"><a href="https://oriolrius.cat/sobre-mi/" class="elementor-item menu-link">Sobre mi</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11223"><a href="https://oriolrius.cat/contacto/" class="elementor-item menu-link">Contacto</a></li>
</ul>			</nav>
					<div class="elementor-menu-toggle" role="button" tabindex="0" aria-label="Menu Toggle" aria-expanded="false">
			<i aria-hidden="true" role="presentation" class="elementor-menu-toggle__icon--open eicon-menu-bar"></i><i aria-hidden="true" role="presentation" class="elementor-menu-toggle__icon--close eicon-close"></i>		</div>
					<nav class="elementor-nav-menu--dropdown elementor-nav-menu__container" aria-hidden="true">
				<ul id="menu-2-a99337d" class="elementor-nav-menu"><li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-9718"><a aria-expanded="false" href="https://oriolrius.cat/category/tech-2-ca/" class="elementor-item menu-link" tabindex="-1">Technology<span role="button" class="dropdown-menu-toggle ast-header-navigation-arrow" tabindex="0" aria-expanded="false" aria-label="Menu Toggle" aria-haspopup="true"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span></span></a>
<ul class="sub-menu elementor-nav-menu--dropdown">
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10535"><a href="https://oriolrius.cat/category/office-tech-2-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>BPM, ERP, CRM and other office applications</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10536"><a href="https://oriolrius.cat/category/programming-tech-2-ca-2/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Development, Models and Methodologies</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10537"><a href="https://oriolrius.cat/category/diy-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Domotics, Electronics and DIY projects</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10538"><a href="https://oriolrius.cat/category/multimedia-tech-2-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Multimedia, Gadgets, Mobile phones and Tablets</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10539"><a href="https://oriolrius.cat/category/networking-tech-2-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Networking and Internet</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10540"><a href="https://oriolrius.cat/category/sysadmin-tech-2-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>System administration, Databases, Messaging and Security</a></li>
</ul>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-has-children menu-item-9716"><a aria-expanded="false" href="https://oriolrius.cat/category/cp-ca/" class="elementor-item menu-link" tabindex="-1">Crecimiento personal<span role="button" class="dropdown-menu-toggle ast-header-navigation-arrow" tabindex="0" aria-expanded="false" aria-label="Menu Toggle" aria-haspopup="true"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span></span></a>
<ul class="sub-menu elementor-nav-menu--dropdown">
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10528"><a href="https://oriolrius.cat/category/cp-ca/coaching-cp-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Business coaching</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10529"><a href="https://oriolrius.cat/category/cp-ca/ciencia-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Ciencia y sociedad</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10530"><a href="https://oriolrius.cat/category/cp-ca/mindfulness-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Conciencia Plena</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10531"><a href="https://oriolrius.cat/category/cp-ca/branding-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Personal Branding</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10532"><a href="https://oriolrius.cat/category/cp-ca/pnl-cp-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>PNL</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10533"><a href="https://oriolrius.cat/category/cp-ca/gtd-cp-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Productividad Personal</a></li>
	<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-10534"><a href="https://oriolrius.cat/category/cp-ca/salud-alimentacion-ca/" class="elementor-sub-item menu-link" tabindex="-1"><span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>Salud y alimentación</a></li>
</ul>
</li>
<li class="menu-item menu-item-type-taxonomy menu-item-object-category menu-item-9717"><a href="https://oriolrius.cat/category/mussol-ca/" class="elementor-item menu-link" tabindex="-1">Mussol</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11222"><a href="https://oriolrius.cat/sobre-mi/" class="elementor-item menu-link" tabindex="-1">Sobre mi</a></li>
<li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-11223"><a href="https://oriolrius.cat/contacto/" class="elementor-item menu-link" tabindex="-1">Contacto</a></li>
</ul>			</nav>
						</div>
				</div>
				<section data-particle_enable="false" data-particle-mobile-disabled="false" class="elementor-section elementor-inner-section elementor-element elementor-element-5240903 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="5240903" data-element_type="section" data-e-type="section">
						<div class="elementor-container elementor-column-gap-default">
					<div class="elementor-column elementor-col-100 elementor-inner-column elementor-element elementor-element-10a3546" data-id="10a3546" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<div class="elementor-element elementor-element-59842c6 elementor-search-form--button-type-text elementor-search-form--skin-classic elementor-widget elementor-widget-search-form" data-id="59842c6" data-element_type="widget" data-e-type="widget" data-settings="{&quot;skin&quot;:&quot;classic&quot;}" data-widget_type="search-form.default">
				<div class="elementor-widget-container">
							<search role="search">
			<form class="elementor-search-form" action="https://oriolrius.cat" method="get">
												<div class="elementor-search-form__container">
					<label class="elementor-screen-only" for="elementor-search-form-59842c6">Search</label>

					
					<input id="elementor-search-form-59842c6" placeholder="Buscar..." class="elementor-search-form__input" type="search" name="s" value="">
					
											<button class="elementor-search-form__submit" type="submit" aria-label="Search">
															Buscar													</button>
					
									</div>
			</form>
		</search>
						</div>
				</div>
					</div>
		</div>
					</div>
		</section>
					</div>
		</div>
					</div>
		</header>
				</header>
			<div id="content" class="site-content">
		<div class="ast-container">
		

	<div id="primary" class="content-area primary">

		
					<main id="main" class="site-main">
				<article
class="post-9608 page type-page status-publish has-post-thumbnail ast-article-single" id="post-9608" itemtype="https://schema.org/CreativeWork" itemscope="itemscope">
	
				<header class="entry-header ast-no-thumbnail ast-no-title ast-header-without-markup">
							</header> <!-- .entry-header -->
		
<div class="entry-content clear"
	itemprop="text">

	
			<div data-elementor-type="wp-page" data-elementor-id="9608" class="elementor elementor-9608" data-elementor-post-type="page">
						<section data-particle_enable="false" data-particle-mobile-disabled="false" class="elementor-section elementor-top-section elementor-element elementor-element-1b736bb elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="1b736bb" data-element_type="section" data-e-type="section">
						<div class="elementor-container elementor-column-gap-default">
					<div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-fd8a709" data-id="fd8a709" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<div class="elementor-element elementor-element-6ad2c7b elementor-widget elementor-widget-posts" data-id="6ad2c7b" data-element_type="widget" data-e-type="widget" data-settings="{&quot;pagination_type&quot;:&quot;numbers_and_prev_next&quot;,&quot;full_content_row_gap&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:35,&quot;sizes&quot;:[]}}" data-widget_type="posts.full_content">
				<div class="elementor-widget-container">
							<div class="elementor-posts-container elementor-posts elementor-posts--skin-full_content elementor-grid" role="list">
				<article class="elementor-post elementor-grid-item post-13075 post type-post status-publish format-standard hentry category-cp-ca category-mussol-ca category-pnl-cp-ca" role="listitem">
				<div class="elementor-post__text">
				<h3 class="elementor-post__title">
			<a href="https://oriolrius.cat/2025/05/09/avui-en-faig-48/" >
				Avui en faig 48			</a>
		</h3>
				<div class="elementor-post__meta-data">
					<span class="elementor-post-date">
			2025/05/09		</span>
				<span class="elementor-post-time">
			12:14		</span>
				</div>
		


<p>Avui compleixo 48, i si alguna cosa m&#8217;ha ensenyat el temps és que l&#8217;experiència no arriba només amb els anys, sinó amb les vivències que ens transformen.</p>



<p>Fa molt vaig entendre que la vida no et dona manuals. Et dona moments. I alguns d&#8217;ells et trenquen per dins&#8230; però també són els que t&#8217;ajuden a créixer de veritat.</p>



<p>&#8211; La mort del meu pare va ser el primer gran cop. Ho recordo en detalls petits, invisibles per als altres però inesborrables per a mi. Encara avui, qualsevol gest quotidià pot portar-me la seva imatge.</p>



<p>&#8211; L&#8217;accident de cotxe va marcar el final de la meva adolescència i l&#8217;inici d&#8217;una nova manera de veure el món.</p>



<p>&#8211; La pèrdua del meu fill Pol ha estat, sens dubte, l&#8217;experiència més dura. Encara avui, recordar-ho m&#8217;omple els ulls de llàgrimes… però també m&#8217;ha ensenyat a valorar i agrair cada instant amb més intensitat.</p>



<p>Amb els anys he après a mirar la vida com un rellotge de sorra.<br>La sorra que ja ha caigut ha perdut el seu color original: s&#8217;ha convertit en experiència.<br>I la que queda a dalt… ja no té l&#8217;energia dels 20 anys. Als 48, aquesta energia canvia, però gana en consciència, en sentit, en profunditat.</p>



<p>El pas del temps no és lineal, ni just, ni previsible. Però sí que podem triar com mirar-ho: amb nostàlgia o amb gratitud.<br>Jo he triat agrair.<br>He triat construir.<br>I, sobretot, he triat ser fidel a mi mateix.</p>



<p> La vida no va de trobar-se, va de crear-se.<br>I sí, avui avui m&#8217;he llevat a les 5 del matí per a escriure això, perquè em recorda qui soc, d&#8217;on vinc i tot el que encara em queda per viure.</p>



<p>Gràcies a totes les persones que m&#8217;heu acompanyat en aquest viatge.<br>La millor recompensa? La família que hem creat&nbsp;Estefania&nbsp;i jo, que s&#8217;ha convertit en el Sol al voltant del qual gira tot.</p>



<figure class="wp-block-image size-medium is-resized"><a href="https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48.jpg"><img fetchpriority="high" fetchpriority="high" decoding="async" width="169" height="300" src="https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48-169x300.jpg" alt="" class="wp-image-13076" style="width:410px;height:auto" srcset="https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48-169x300.jpg 169w, https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48-576x1024.jpg 576w, https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48-768x1366.jpg 768w, https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48-864x1536.jpg 864w, https://oriolrius.cat/wp-content/uploads/2025/05/Oriol_post_web_cumple_48.jpg 899w" sizes="(max-width: 169px) 100vw, 169px" /></a></figure>



<p>Avui, més que mai, em sento plenament autor d&#8217;aquesta obra que anomenem vida.</p>



<p></p>



<p>#FeliçAniversari  #CreixementPersonal  #Gratitud #PNL #Experiència #Feliços48 #Tete i #Fàtima</p>



<p></p>
		</div>
				</article>
				<article class="elementor-post elementor-grid-item post-12929 post type-post status-publish format-standard hentry category-sysadmin-tech-2-ca category-tech-2-cat tag-commandline tag-customdns tag-digcommand tag-dnsconfiguration tag-dnsforwarding tag-dnsmasq tag-dnsresolver tag-dnsserver tag-dnstroubleshooting tag-domainspecificdns tag-itinfrastructure tag-linux tag-netplan tag-networkmanagement tag-networksecurity tag-per-domaindns tag-systemd-resolved tag-ubuntu tag-ubuntu2404 tag-wsl" role="listitem">
				<div class="elementor-post__text">
				<h3 class="elementor-post__title">
			<a href="https://oriolrius.cat/2025/02/20/implementing-per-domain-dns-configuration-on-linux-ubuntu-using-dnsmasq/" >
				Implementing Per-Domain DNS Configuration on Linux Ubuntu Using dnsmasq			</a>
		</h3>
				<div class="elementor-post__meta-data">
					<span class="elementor-post-date">
			2025/02/20		</span>
				<span class="elementor-post-time">
			19:42		</span>
				</div>
		


<p>In Linux, managing network traffic is essential for a robust and secure IT infrastructure. In this post, we focus on Ubuntu—whether running on a virtual machine, Windows Subsystem for Linux (WSL), or a physical machine running Ubuntu 24.04. We will configure per-domain DNS rules using <strong>dnsmasq</strong>. This guide also covers additional considerations for WSL and systems using netplan.</p>



<h2 class="wp-block-heading">Configuring Ubuntu for Local DNS with dnsmasq</h2>



<p>When using Ubuntu, you might be using <strong>netplan</strong> for network configuration. In that case, you need to configure netplan to use the local DNS server provided by dnsmasq. Make sure your netplan configuration (e.g., <code>/etc/netplan/01-netcfg.yaml</code>) sets the DNS to <code>127.0.0.1</code>, so that all DNS queries are forwarded to your local dnsmasq server.</p>



<h3 class="wp-block-heading">Disabling systemd-resolved</h3>



<p>Ubuntu often uses <strong>systemd-resolved</strong> by default, which can interfere with your custom DNS setup. To prevent conflicts, disable and stop systemd-resolved using the following commands:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="sudo systemctl disable systemd-resolved
sudo systemctl stop systemd-resolved
sudo systemctl daemon-reload
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">disable</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemd-resolved</span></span>
<span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">stop</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemd-resolved</span></span>
<span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">daemon-reload</span></span>
<span class="line"></span></code></pre></div>



<p>This ensures that systemd-resolved does not override your DNS settings.</p>



<h3 class="wp-block-heading">Note for WSL Users</h3>



<p>If you are running Ubuntu under WSL, you need to prevent WSL from overwriting your DNS settings. Edit or create the file <strong>/etc/wsl.conf</strong> with the following content:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="[network]
generateResolvConf = false
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9FF">network</span><span style="color: #ECEFF4">]</span></span>
<span class="line"><span style="color: #88C0D0">generateResolvConf</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">false</span></span>
<span class="line"></span></code></pre></div>



<p>Then, create or edit the <strong>/etc/resolv.conf</strong> file to include:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="nameserver 127.0.0.1
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">nameserver</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">127.0</span><span style="color: #A3BE8C">.0.1</span></span>
<span class="line"></span></code></pre></div>



<p>This ensures that your system uses the local dnsmasq server.</p>



<h2 class="wp-block-heading">Installing and Setting Up dnsmasq</h2>



<h3 class="wp-block-heading">Step 1: Install dnsmasq</h3>



<p>First, update your package list and install dnsmasq:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="sudo apt update
sudo apt install dnsmasq
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">apt</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">update</span></span>
<span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">apt</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dnsmasq</span></span>
<span class="line"></span></code></pre></div>



<h3 class="wp-block-heading">Step 2: Enable and Verify the dnsmasq Service</h3>



<p>After installing dnsmasq, enable the service and check its status to ensure it is running correctly:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="sudo systemctl enable dnsmasq
sudo systemctl daemon-reload
sudo systemctl start dnsmasq
sudo systemctl status dnsmasq
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">enable</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dnsmasq</span></span>
<span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">daemon-reload</span></span>
<span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">start</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dnsmasq</span></span>
<span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">status</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dnsmasq</span></span>
<span class="line"></span></code></pre></div>



<p>You should see that dnsmasq is active and running. This local DNS server will be used to resolve all DNS queries forwarded from your system.</p>



<h3 class="wp-block-heading">Step 3: Configure dnsmasq</h3>



<p>Edit the <strong>/etc/dnsmasq.conf</strong> file to set up your DNS rules. Here’s an example configuration:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# Default upstream DNS servers
server=8.8.8.8
server=8.8.4.4

# Domain-specific DNS servers
server=/domain01.tld/172.30.0.1
server=/domain02.tld/172.30.0.2
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># Default upstream DNS servers</span></span>
<span class="line"><span style="color: #D8DEE9">server</span><span style="color: #81A1C1">=</span><span style="color: #B48EAD">8.8</span><span style="color: #A3BE8C">.8.8</span></span>
<span class="line"><span style="color: #D8DEE9">server</span><span style="color: #81A1C1">=</span><span style="color: #B48EAD">8.8</span><span style="color: #A3BE8C">.4.4</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Domain-specific DNS servers</span></span>
<span class="line"><span style="color: #D8DEE9">server</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">/domain01.tld/172.30.0.1</span></span>
<span class="line"><span style="color: #D8DEE9">server</span><span style="color: #81A1C1">=</span><span style="color: #A3BE8C">/domain02.tld/172.30.0.2</span></span>
<span class="line"></span></code></pre></div>



<p><strong>Explanation:</strong></p>



<ul class="wp-block-list">
<li>The lines <code>server=8.8.8.8</code> and <code>server=8.8.4.4</code> set Google’s public DNS as the default upstream DNS servers. When a query does not match any domain-specific rule, dnsmasq will forward the request to these servers.</li>



<li>The lines <code>server=/domain01.tld/172.30.0.1</code> and <code>server=/domain02.tld/172.30.0.2</code> specify that queries for any host within <code>domain01.tld</code> and <code>domain02.tld</code> should be resolved by the DNS servers at <code>172.30.0.1</code> and <code>172.30.0.2</code>, respectively.</li>
</ul>



<p>After making your changes, save the file and restart dnsmasq to apply the new configuration:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="sudo systemctl restart dnsmasq
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">systemctl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">restart</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dnsmasq</span></span>
<span class="line"></span></code></pre></div>



<h2 class="wp-block-heading">Verifying the DNS Configuration</h2>



<p>You can use the <code>dig</code> command to verify that your DNS rules are working as expected. Note that when your system’s resolver is set to use dnsmasq at <code>127.0.0.1</code>, the dig output will always show <code>SERVER: 127.0.0.1#53</code>. However, dnsmasq will forward the query internally to the appropriate upstream DNS server based on your configuration.</p>



<p>Below are two examples: one for a public domain (google.com) and one for a domain that should be resolved by your custom DNS rule (example01.tld).</p>



<h3 class="wp-block-heading">Example 1: Verifying a Public Domain (google.com)</h3>



<p>Run the following command:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="dig google.com
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">dig</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">google.com</span></span>
<span class="line"></span></code></pre></div>



<p><strong>Simulated Output:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="; <<&gt;&gt; DiG 9.11.3-1ubuntu1-Ubuntu <<&gt;&gt; google.com
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER<<- opcode: QUERY, status: NOERROR, id: 12345
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;google.com.                    IN      A
;; ANSWER SECTION:
google.com.             300     IN      A       172.217.164.110
google.com.             300     IN      A       172.217.164.78
;; Query time: 23 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Feb 20 10:00:00 UTC 2025
;; MSG SIZE  rcvd: 113
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #A3BE8C">; &lt;&lt;&gt;&gt; DiG 9.11.3-1ubuntu1-Ubuntu &lt;&lt;&gt;&gt; google.com</span></span>
<span class="line"><span style="color: #8FBCBB">;; global options</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+cmd</span></span>
<span class="line"><span style="color: #8FBCBB">;; Got answer</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #8FBCBB">;; -&gt;&gt;HEADER&lt;&lt;- opcode</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">QUERY, status</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">NOERROR, id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">12345</span></span>
<span class="line"><span style="color: #8FBCBB">;; flags</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">qr rd ra; QUERY</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">1, ANSWER</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">2, AUTHORITY</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">0, ADDITIONAL</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #8FBCBB">;; QUESTION SECTION</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #A3BE8C">;google.com.                    IN      A</span></span>
<span class="line"><span style="color: #8FBCBB">;; ANSWER SECTION</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #A3BE8C">google.com.             300     IN      A       172.217.164.110</span></span>
<span class="line"><span style="color: #A3BE8C">google.com.             300     IN      A       172.217.164.78</span></span>
<span class="line"><span style="color: #8FBCBB">;; Query time</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">23 msec</span></span>
<span class="line"><span style="color: #8FBCBB">;; SERVER</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">127.0.0.1#53(127.0.0.1)</span></span>
<span class="line"><span style="color: #8FBCBB">;; WHEN</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Wed Feb 20 10:00:00 UTC 2025</span></span>
<span class="line"><span style="color: #8FBCBB">;; MSG SIZE  rcvd</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">113</span></span>
<span class="line"></span></code></pre></div>



<p><strong>Internal Process:</strong></p>



<ul class="wp-block-list">
<li><strong>Step 1:</strong> The query for <code>google.com</code> is sent to the local dnsmasq server at <code>127.0.0.1</code>.</li>



<li><strong>Step 2:</strong> dnsmasq examines its configuration and sees that <code>google.com</code> does not match any domain-specific rules.</li>



<li><strong>Step 3:</strong> It then forwards the query to the default upstream DNS servers (<code>8.8.8.8</code> and <code>8.8.4.4</code>).</li>



<li><strong>Step 4:</strong> The upstream server resolves <code>google.com</code> and returns the result back to dnsmasq, which then passes it back to the client.</li>
</ul>



<h3 class="wp-block-heading">Example 2: Verifying a Domain with a Custom DNS Rule (example01.tld)</h3>



<p>Run the following command:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="dig example01.tld
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">dig</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">example01.tld</span></span>
<span class="line"></span></code></pre></div>



<p><strong>Simulated Output:</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="; <<&gt;&gt; DiG 9.11.3-1ubuntu1-Ubuntu <<&gt;&gt; example01.tld
;; global options: +cmd
;; Got answer:
;; -&gt;&gt;HEADER<<- opcode: QUERY, status: NOERROR, id: 67890
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; QUESTION SECTION:
;example01.tld.               IN      A
;; ANSWER SECTION:
example01.tld.           60      IN      A       172.30.0.1
;; Query time: 25 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Feb 20 10:00:10 UTC 2025
;; MSG SIZE  rcvd: 82
" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #A3BE8C">; &lt;&lt;&gt;&gt; DiG 9.11.3-1ubuntu1-Ubuntu &lt;&lt;&gt;&gt; example01.tld</span></span>
<span class="line"><span style="color: #8FBCBB">;; global options</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">+cmd</span></span>
<span class="line"><span style="color: #8FBCBB">;; Got answer</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #8FBCBB">;; -&gt;&gt;HEADER&lt;&lt;- opcode</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">QUERY, status</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">NOERROR, id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">67890</span></span>
<span class="line"><span style="color: #8FBCBB">;; flags</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">qr rd ra; QUERY</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">1, ANSWER</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">1, AUTHORITY</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">0, ADDITIONAL</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #8FBCBB">;; QUESTION SECTION</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #A3BE8C">;example01.tld.               IN      A</span></span>
<span class="line"><span style="color: #8FBCBB">;; ANSWER SECTION</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #A3BE8C">example01.tld.           60      IN      A       172.30.0.1</span></span>
<span class="line"><span style="color: #8FBCBB">;; Query time</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">25 msec</span></span>
<span class="line"><span style="color: #8FBCBB">;; SERVER</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">127.0.0.1#53(127.0.0.1)</span></span>
<span class="line"><span style="color: #8FBCBB">;; WHEN</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">Wed Feb 20 10:00:10 UTC 2025</span></span>
<span class="line"><span style="color: #8FBCBB">;; MSG SIZE  rcvd</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">82</span></span>
<span class="line"></span></code></pre></div>



<p><strong>Internal Process:</strong></p>



<ul class="wp-block-list">
<li><strong>Step 1:</strong> The query for <code>example01.tld</code> is sent to dnsmasq at <code>127.0.0.1</code>.</li>



<li><strong>Step 2:</strong> dnsmasq checks its configuration and finds a matching domain-specific rule for <code>example01.tld</code>, which directs the query to the DNS server at <code>172.30.0.1</code>.</li>



<li><strong>Step 3:</strong> dnsmasq forwards the query internally to <code>172.30.0.1</code> without exposing this step in the client’s dig output.</li>



<li><strong>Step 4:</strong> The upstream server at <code>172.30.0.1</code> resolves the query, and dnsmasq returns the answer to the client.</li>
</ul>



<p>In both cases, while the client sees the query being handled by <code>127.0.0.1</code>, dnsmasq intelligently directs the queries to the appropriate upstream servers based on your configuration. This seamless internal forwarding is what allows you to manage per-domain DNS resolution effectively.</p>



<h2 class="wp-block-heading">Conclusion: Why Use Per-Domain DNS Configuration?</h2>



<p>Implementing per-domain DNS configuration on Linux Ubuntu is a powerful way to gain granular control over your network’s behavior. This approach is particularly useful for:</p>



<ul class="wp-block-list">
<li><strong>Enterprise Environments:</strong> Where internal domains require different DNS resolutions from external queries.</li>



<li><strong>Development and Testing:</strong> Allowing developers to redirect domain requests to local or test servers.</li>



<li><strong>Security:</strong> Enhancing network security by segregating traffic and reducing reliance on external DNS servers.</li>
</ul>



<p>By configuring dnsmasq with domain-specific rules and ensuring that your system points to the local DNS (especially important when using netplan or running under WSL), you optimize network performance and security tailored to your specific needs.</p>
		</div>
				</article>
				<article class="elementor-post elementor-grid-item post-12873 post type-post status-publish format-standard hentry category-tech-2-cat" role="listitem">
				<div class="elementor-post__text">
				<h3 class="elementor-post__title">
			<a href="https://oriolrius.cat/2025/02/20/web-based-swagger-api-documentation-and-client/" >
				Web-based Swagger API documentation and client			</a>
		</h3>
				<div class="elementor-post__meta-data">
					<span class="elementor-post-date">
			2025/02/20		</span>
				<span class="elementor-post-time">
			06:46		</span>
				</div>
		


<p>For example, we use NPM (Nginx Proxy Manager). The Web User Interface (WUI) of NPM relies on a backend API. By inspecting your browser’s network requests, you can observe how it functions.</p>



<p>However, I was unable to find comprehensive documentation for this API. With a bit of research, you can discover that the NPM API exposes its schema in a specific location:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="https://npm.your-domain.tld/api/schema" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">https://npm.your-domain.tld/api/schema</span></span></code></pre></div>



<p>If you&#8217;re looking for a convenient web-based API client along with a documented interface to help you understand how to use it, simply run the following Docker container:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="docker run -p 80:8080 -d swaggerapi/swagger-ui" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">docker</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">80</span><span style="color: #A3BE8C">:8080</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-d</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">swaggerapi/swagger-ui</span></span></code></pre></div>



<p>Open your browser and navigate to http://localhost, and you will see something like this:</p>



<figure class="wp-block-image size-large"><a href="https://oriolrius.cat/wp-content/uploads/2025/01/image-3.png"><img decoding="async" width="1024" height="577" src="https://oriolrius.cat/wp-content/uploads/2025/01/image-3-1024x577.png" alt="" class="wp-image-12874" srcset="https://oriolrius.cat/wp-content/uploads/2025/01/image-3-1024x577.png 1024w, https://oriolrius.cat/wp-content/uploads/2025/01/image-3-400x225.png 400w, https://oriolrius.cat/wp-content/uploads/2025/01/image-3-768x432.png 768w, https://oriolrius.cat/wp-content/uploads/2025/01/image-3-1536x865.png 1536w, https://oriolrius.cat/wp-content/uploads/2025/01/image-3.png 1918w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>Finally, replace the Petstore API URL with your own, such as https://npm.your-domain.tld/api/schema, or any OpenAPI URL you wish to use.</p>



<p>Below is a screenshot of my local NPM setup:</p>



<figure class="wp-block-image size-large"><a href="https://oriolrius.cat/wp-content/uploads/2025/01/image-4.png"><img decoding="async" width="1024" height="577" src="https://oriolrius.cat/wp-content/uploads/2025/01/image-4-1024x577.png" alt="" class="wp-image-12875" srcset="https://oriolrius.cat/wp-content/uploads/2025/01/image-4-1024x577.png 1024w, https://oriolrius.cat/wp-content/uploads/2025/01/image-4-400x225.png 400w, https://oriolrius.cat/wp-content/uploads/2025/01/image-4-768x432.png 768w, https://oriolrius.cat/wp-content/uploads/2025/01/image-4-1536x865.png 1536w, https://oriolrius.cat/wp-content/uploads/2025/01/image-4.png 1918w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>



<p>I hope this post has been helpful to you. Thank you for taking the time to read it.</p>
		</div>
				</article>
				<article class="elementor-post elementor-grid-item post-12913 post type-post status-publish format-standard hentry category-tech-2-cat" role="listitem">
				<div class="elementor-post__text">
				<h3 class="elementor-post__title">
			<a href="https://oriolrius.cat/2025/02/18/formatos-de-certificados-pem-der-y-pkcs12-y-manipulacion-de-claves-privadas/" >
				Formatos de Certificados: PEM, DER y PKCS#12 y Manipulación de Claves Privadas			</a>
		</h3>
				<div class="elementor-post__meta-data">
					<span class="elementor-post-date">
			2025/02/18		</span>
				<span class="elementor-post-time">
			14:41		</span>
				</div>
		


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



<ol class="wp-block-list">
<li><a href="https://oriolrius.cat/2025/01/31/12824/" data-type="link" data-id="https://oriolrius.cat/2025/01/31/12824/">Gestión de certificados (PKI) &#8211; easy-rsa</a></li>



<li><a href="https://oriolrius.cat/2025/02/07/mqtt-broker-mosquitto-con-certificado-servidor-self-signed/">MQTT Broker (Mosquitto) con certificado servidor (self-signed)</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-self-signed-y-certificado-en-los-clientes/">MQTT Broker (Mosquitto) con certificado servidor (self-signed) y certificado en los clientes</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-lets-encrypt/">MQTT Broker (Mosquitto) con certificado servidor (Let&#8217;s Encrypt)</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/formatos-de-certificados-pem-der-y-pkcs12-y-manipulacion-de-claves-privadas/">Formatos de Certificados: PEM, DER y PKCS#12 y Manipulación de Claves Privadas</a></li>
</ol>



<h2 class="wp-block-heading">Introducción</h2>



<p>En este artículo explicamos de manera práctica los formatos más comunes de certificados digitales y cómo manipular las claves privadas asociadas. Conocer estos formatos y comandos te permitirá gestionar correctamente tus certificados para su uso en entornos que requieren seguridad y automatización.</p>



<h2 class="wp-block-heading">Formatos de Certificados</h2>



<h3 class="wp-block-heading">Formato PEM (Privacy Enhanced Mail)</h3>



<p>El formato <strong>PEM</strong> es legible por humanos, ya que utiliza una codificación Base64 en ASCII. Un certificado en este formato comienza con la línea <code>----BEGIN CERTIFICATE----</code>. Este es el formato requerido para instalar certificados en el <em>trust store</em> (conjunto de certificados de entidades de confianza).</p>



<h3 class="wp-block-heading">Formato DER (Distinguished Encoding Rules)</h3>



<p>El formato <strong>DER</strong> es un formato binario, más compacto y no legible directamente. Si al inspeccionar tu certificado no ves la línea inicial típica de PEM, probablemente se trate de un certificado en formato DER.</p>



<h2 class="wp-block-heading">Conversión de DER a PEM</h2>



<p>Para instalar un certificado en el <em>trust store</em>, es necesario que esté en formato PEM. Si dispones de un certificado en formato DER, por ejemplo <code>local-ca.der</code>, puedes convertirlo a PEM usando el siguiente comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="sudo openssl x509 -inform der -outform pem -in local-ca.der -out local-ca.crt" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">sudo</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">x509</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-inform</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">der</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-outform</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pem</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-in</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">local-ca.der</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-out</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">local-ca.crt</span></span></code></pre></div>



<h2 class="wp-block-heading">Formato PKCS#12</h2>



<p>El formato <strong>PKCS#12</strong> permite empaquetar tanto el certificado como la clave privada y, opcionalmente, la <em>certificate chain</em> (secuencia de certificados intermedios que verifican la validez del certificado). Es muy útil para exportar e importar credenciales completas de forma segura, ya que el archivo resultante (normalmente con extensión <code>.p12</code>) puede estar protegido por una contraseña.<br>Es importante tener en cuenta que, si la clave privada de un certificado no se encuentra dentro de la PKI, no se podrá exportar en formato PKCS#12.<br>En el entorno de <em>easy-rsa</em>, puedes exportar un certificado y su clave privada en formato PKCS#12 con el siguiente comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# sintaxis:
./easyrsa export-p12 &lt;nombre-del-certificado|FQDN&gt;

# ejemplo:
./easyrsa export-p12 mqtt.ymbihq.local" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># sintaxis:</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">export-p12</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #A3BE8C">nombre-del-certificado</span><span style="color: #81A1C1">|</span><span style="color: #88C0D0">FQDN&gt;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># ejemplo:</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">export-p12</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt.ymbihq.local</span></span></code></pre></div>



<h2 class="wp-block-heading">Manipulación de Claves Privadas</h2>



<p>Las claves privadas suelen estar protegidas mediante cifrado simétrico, lo que significa que se necesita una passphrase (contraseña) para descifrarlas y utilizarlas. Esta protección es fundamental para evitar el uso no autorizado de la clave en caso de pérdida o robo. En ocasiones, es necesario eliminar o modificar la passphrase para facilitar su uso en ciertos entornos o automatizaciones.</p>



<h3 class="wp-block-heading">Eliminar la Passphrase</h3>



<p>Para eliminar la passphrase de una clave privada, puedes usar el siguiente comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="openssl rsa -in [original.key] -out [new.key]" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">rsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-in</span><span style="color: #D8DEE9FF"> [original.key] -out </span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9FF">new.key</span><span style="color: #ECEFF4">]</span></span></code></pre></div>



<p>Si prefieres realizarlo de manera no interactiva, especificando la contraseña directamente en el comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="openssl rsa -in original.key -out new.key -passin pass:your_original_passphrase" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">rsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-in</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">original.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-out</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">new.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-passin</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pass:your_original_passphrase</span></span></code></pre></div>



<h3 class="wp-block-heading">Cambiar la Passphrase</h3>



<p>Si deseas cambiar la passphrase y proteger la clave con un nuevo cifrado (por ejemplo, AES-256), puedes hacerlo de la siguiente forma:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="openssl rsa -aes256 -in original.key -out new.key" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">rsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-aes256</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-in</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">original.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-out</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">new.key</span></span></code></pre></div>



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



<p>Con la información explicada en este artículo, podrás gestionar y convertir certificados entre formatos PEM y DER, empaquetar tus credenciales en formato PKCS#12 y manipular las claves privadas según tus necesidades. Estos conocimientos te permitirán implementar soluciones seguras y automatizadas en tus entornos de desarrollo y producción.</p>
		</div>
				</article>
				<article class="elementor-post elementor-grid-item post-12901 post type-post status-publish format-standard hentry category-tech-2-cat" role="listitem">
				<div class="elementor-post__text">
				<h3 class="elementor-post__title">
			<a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-lets-encrypt/" >
				MQTT Broker (Mosquitto) con certificado servidor (Let&#8217;s Encrypt)			</a>
		</h3>
				<div class="elementor-post__meta-data">
					<span class="elementor-post-date">
			2025/02/18		</span>
				<span class="elementor-post-time">
			13:06		</span>
				</div>
		


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



<ol class="wp-block-list">
<li><a href="https://oriolrius.cat/2025/01/31/12824/" data-type="link" data-id="https://oriolrius.cat/2025/01/31/12824/">Gestión de certificados (PKI) &#8211; easy-rsa</a></li>



<li><a href="https://oriolrius.cat/2025/02/07/mqtt-broker-mosquitto-con-certificado-servidor-self-signed/">MQTT Broker (Mosquitto) con certificado servidor (self-signed)</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-self-signed-y-certificado-en-los-clientes/">MQTT Broker (Mosquitto) con certificado servidor (self-signed) y certificado en los clientes</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-lets-encrypt/">MQTT Broker (Mosquitto) con certificado servidor (Let&#8217;s Encrypt)</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/formatos-de-certificados-pem-der-y-pkcs12-y-manipulacion-de-claves-privadas/">Formatos de Certificados: PEM, DER y PKCS#12 y Manipulación de Claves Privadas</a></li>
</ol>



<h2 class="wp-block-heading">Introducción</h2>



<p>En este post presentamos un <strong>proof-of-concept</strong> para configurar un broker MQTT utilizando Mosquitto, en el que se implementa TLS gracias a los certificados de Let&#8217;s Encrypt. Este método aporta varias ventajas frente a las soluciones tradicionales:</p>



<ul class="wp-block-list">
<li><strong>No requiere exposición pública:</strong> El servidor no tiene que estar expuesto a Internet; únicamente el nombre de dominio debe resolverse correctamente en DNS, lo que minimiza la superficie de ataque.</li>



<li><strong>Facilidad de uso:</strong> Con Certbot y herramientas automatizadas (como Just), se simplifica el proceso de emisión y renovación de certificados.</li>



<li><strong>Rentable:</strong> Let&#8217;s Encrypt ofrece certificados gratuitos, reduciendo costes operativos.</li>
</ul>



<p>Esta aproximación es ideal para entornos privados, de desarrollo o pruebas de concepto, donde se desea un equilibrio entre seguridad y comodidad.</p>



<h2 class="wp-block-heading">Demostración en vídeo</h2>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="MQTT Broker (Mosquitto) con certificado servidor (Let’s Encrypt)" width="1200" height="675" src="https://www.youtube.com/embed/t5UNog-x9sw?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



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



<ul class="wp-block-list">
<li><strong>Nombre de dominio:</strong> Un dominio válido (por ejemplo, <code>mqtt.example.com</code>).</li>



<li><strong>Certbot:</strong> Herramienta para obtener certificados de Let&#8217;s Encrypt.</li>



<li><strong>Just:</strong> Un <em>command runner</em> que simplifica la ejecución de tareas (consulta el <a href="./Justfile">Justfile</a> para ver los comandos disponibles).</li>



<li><strong>Mosquitto:</strong> El software del broker MQTT.</li>
</ul>



<h2 class="wp-block-heading">Configuración</h2>



<h3 class="wp-block-heading">Obtención de Certificados con Certbot</h3>



<p>Let&#8217;s Encrypt permite obtener certificados TLS gratuitos y automatizados. Ten en cuenta que, a diferencia de otras implementaciones, Let&#8217;s Encrypt <strong>no</strong> soporta certificados para clientes, por lo que solo se generará el certificado para el servidor.</p>



<p>Existen dos métodos habituales para validar la propiedad del dominio:</p>



<ul class="wp-block-list">
<li><strong>HTTP-01 Challenge:</strong> Requiere disponer de un servidor web en funcionamiento.</li>



<li><strong>DNS-01 Challenge:</strong> Consiste en añadir un registro TXT en el DNS, ideal si no dispones de una IP pública o de un servidor web.</li>
</ul>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><strong>Importante:</strong> Asegúrate de que el nombre distinguido (DN) del certificado coincide exactamente con el hostname que usarán los clientes para conectarse y que este se resuelve correctamente en DNS.</p>
</blockquote>



<h4 class="wp-block-heading">Instalación</h4>



<p>Para comenzar, crea un entorno virtual e instala Certbot:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="uv venv
uv pip install certbot" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">uv</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">venv</span></span>
<span class="line"><span style="color: #88C0D0">uv</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pip</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certbot</span></span></code></pre></div>



<h4 class="wp-block-heading">Solicitud del Certificado</h4>



<p>Emplea la siguiente sintaxis para solicitar el certificado:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="just certbot certonly -m &lt;tu-email&gt; --preferred-challenges dns-01 --manual -d &lt;dominio1&gt;,&lt;dominio2&gt;,..." style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">just</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certbot</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certonly</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-m</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #A3BE8C">tu-emai</span><span style="color: #D8DEE9FF">l</span><span style="color: #81A1C1">&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--preferred-challenges</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dns-01</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--manual</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-d</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">&lt;</span><span style="color: #A3BE8C">dominio</span><span style="color: #81A1C1">1&gt;</span><span style="color: #A3BE8C">,</span><span style="color: #81A1C1">&lt;</span><span style="color: #A3BE8C">dominio</span><span style="color: #81A1C1">2&gt;</span><span style="color: #A3BE8C">,...</span></span></code></pre></div>



<p>Por ejemplo:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="just certbot certonly -m oriol@joor.net --preferred-challenges dns-01 --manual -d mqtt.joor.net,pki.joor.net" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">just</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certbot</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certonly</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-m</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">oriol@joor.net</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--preferred-challenges</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dns-01</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--manual</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-d</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt.joor.net,pki.joor.net</span></span></code></pre></div>



<p>Si la solicitud es exitosa, los certificados se ubicarán en la ruta:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="certbot/config/live/&lt;dominio&gt;" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">certbot/config/live/&lt;dominio&gt;</span></span></code></pre></div>



<p>Dentro de este directorio encontrarás:</p>



<ul class="wp-block-list">
<li><strong><code>privkey.pem</code></strong>: Tu clave privada.</li>



<li><strong><code>fullchain.pem</code></strong>: La cadena completa de certificados, que es la que se utiliza en la mayoría de las configuraciones de servidor.</li>



<li><strong><code>chain.pem</code></strong>: Certificados intermedios (útiles, por ejemplo, para OCSP stapling en Nginx &gt;=1.3.7).</li>



<li><strong><code>cert.pem</code></strong>: Un certificado que puede generar conflictos en algunos escenarios, por lo que generalmente se recomienda utilizar <code>fullchain.pem</code>.</li>
</ul>



<p>Para Mosquitto, solo se requerirán los archivos <code>fullchain.pem</code> y <code>privkey.pem</code>.</p>



<h3 class="wp-block-heading">Ejecución del Broker MQTT</h3>



<p>La configuración de Mosquitto ya está preparada para referenciar los certificados emitidos por Let&#8217;s Encrypt. Para lanzar el servicio, ejecuta:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="just mqtt" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">just</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt</span></span></code></pre></div>



<p>Este comando inicia Mosquitto utilizando el archivo de configuración <code>mosquitto.conf</code>, el cual contiene las rutas correctas a los certificados.</p>



<h2 class="wp-block-heading">Detalles del Certificado</h2>



<ul class="wp-block-list">
<li><strong>Clave Privada (<code>privkey.pem</code>):</strong> Garantiza la identidad segura del servidor.</li>



<li><strong>Cadena Completa (<code>fullchain.pem</code>):</strong> Incluye tanto el certificado del servidor como los certificados intermedios necesarios.</li>
</ul>



<p>Dado que los clientes suelen confiar en las CA de Let&#8217;s Encrypt incluidas en sus sistemas operativos, <strong>no es necesario</strong> proporcionar un certificado CA adicional en el broker.</p>



<h2 class="wp-block-heading">Renovación del Certificado</h2>



<p>Los certificados de Let&#8217;s Encrypt tienen una vigencia de 90 días, por lo que es imprescindible renovarlos periódicamente para mantener la seguridad. Para renovar los certificados, puedes usar:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="just certbot renew
# o alternativamente:
just certbot_renew" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">just</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certbot</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">renew</span></span>
<span class="line"><span style="color: #616E88"># o alternativamente:</span></span>
<span class="line"><span style="color: #88C0D0">just</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certbot_renew</span></span></code></pre></div>



<p>Tras la renovación, si las rutas en el archivo de configuración de Mosquitto permanecen iguales, el broker utilizará automáticamente el nuevo certificado al reiniciarse o al hacer un <em>reload</em> de la configuración.</p>



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



<ul class="wp-block-list">
<li>Esta configuración es una prueba de concepto. Para entornos de producción, considera automatizar completamente el proceso de renovación y revisar otras medidas de seguridad adicionales.</li>



<li>Asegúrate de actualizar los registros DNS para que la validación del dominio se realice sin problemas.</li>



<li>Modifica los archivos de configuración únicamente si comprendes las implicaciones de seguridad asociadas.</li>
</ul>



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



<ul class="wp-block-list">
<li>Repositorio: <a href="https://github.com/oriolrius/mqtt-server-certbot">github.com/mqtt-server-certbot</a></li>



<li>Repositorio: <a href="https://github.com/oriolrius/mqtt-server-n-client-n-server-private-pki">github.com/mqtt-server-n-client-n-server-private-pki</a></li>



<li>Repositorio: <a href="https://github.com/oriolrius/mqtt-server-private-pki">github.com/mqtt-server-private-pki</a></li>



<li><a href="https://mqttx.app/">https://mqttx.app/</a></li>



<li><a href="https://mqttx.app/docs/cli">https://mqttx.app/docs/cli</a></li>



<li><a href="http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/" data-type="link" data-id="http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/">Creating and Using Client Certificates with MQTT and Mosquitto</a></li>



<li><a href="http://www.steves-internet-guide.com/using-lets-encrypt-certificate-mosquitto/" data-type="link" data-id="http://www.steves-internet-guide.com/using-lets-encrypt-certificate-mosquitto/">Using A Lets Encrypt Certificate on Mosquitto</a></li>



<li><a href="http://www.steves-internet-guide.com/ssl-certificates-explained/" data-type="link" data-id="http://www.steves-internet-guide.com/ssl-certificates-explained/">SSL and SSL Certificates Explained For Beginners</a></li>



<li><a href="https://mosquitto.org/man/mosquitto-conf-5.html" data-type="link" data-id="https://mosquitto.org/man/mosquitto-conf-5.html">Mosquitto.conf man</a></li>



<li><a href="https://cedalo.com/blog/enabling-websockets-over-mqtt-with-mosquitto/" data-type="link" data-id="https://cedalo.com/blog/enabling-websockets-over-mqtt-with-mosquitto/">How to Configure MQTT over WebSockets with Mosquitto Broker</a></li>



<li><a href="https://www.emqx.com/en/blog/getting-the-clients-real-ip-when-using-the-nginx-reverse-proxy-emqx#getting-the-mqtt-over-websocket-client-s-real-ip" data-type="link" data-id="https://www.emqx.com/en/blog/getting-the-clients-real-ip-when-using-the-nginx-reverse-proxy-emqx#getting-the-mqtt-over-websocket-client-s-real-ip">Getting the Client&#8217;s Real IP When Using the NGINX Reverse Proxy for EMQX</a></li>
</ul>
		</div>
				</article>
				<article class="elementor-post elementor-grid-item post-12888 post type-post status-publish format-standard hentry category-tech-2-cat" role="listitem">
				<div class="elementor-post__text">
				<h3 class="elementor-post__title">
			<a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-self-signed-y-certificado-en-los-clientes/" >
				MQTT Broker (Mosquitto) con certificado servidor (self-signed) y certificado en los clientes			</a>
		</h3>
				<div class="elementor-post__meta-data">
					<span class="elementor-post-date">
			2025/02/18		</span>
				<span class="elementor-post-time">
			10:28		</span>
				</div>
		


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



<ol class="wp-block-list">
<li><a href="https://oriolrius.cat/2025/01/31/12824/" data-type="link" data-id="https://oriolrius.cat/2025/01/31/12824/">Gestión de certificados (PKI) &#8211; easy-rsa</a></li>



<li><a href="https://oriolrius.cat/2025/02/07/mqtt-broker-mosquitto-con-certificado-servidor-self-signed/">MQTT Broker (Mosquitto) con certificado servidor (self-signed)</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-self-signed-y-certificado-en-los-clientes/">MQTT Broker (Mosquitto) con certificado servidor (self-signed) y certificado en los clientes</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/mqtt-broker-mosquitto-con-certificado-servidor-lets-encrypt/">MQTT Broker (Mosquitto) con certificado servidor (Let&#8217;s Encrypt)</a></li>



<li><a href="https://oriolrius.cat/2025/02/18/formatos-de-certificados-pem-der-y-pkcs12-y-manipulacion-de-claves-privadas/">Formatos de Certificados: PEM, DER y PKCS#12 y Manipulación de Claves Privadas</a></li>
</ol>



<h2 class="wp-block-heading">Descripción del escenario</h2>



<p>En este post vamos a explorar la configuración de un bróker MQTT utilizando Mosquitto, implementando seguridad mutua a través de certificados: un certificado auto-firmado para el servidor y certificados específicos para los clientes. Analizaremos paso a paso cómo montar el entorno, partiendo de una configuración mínima que permita el uso tanto de conexiones TCP como de Websockets.</p>



<p>A lo largo del artículo se demostrará de manera detallada el proceso de negociación de la conexión cifrada utilizando OpenSSL como cliente TCP+SSL/TLS, y posteriormente se emplearán los clientes de Mosquitto para suscribirse y publicar mensajes en un tópico de demostración. Además, veremos cómo consumir el servicio mediante un sencillo script en Python y, para cerrar, utilizaremos el cliente EMQ MQTTX desde la consola, que nos permitirá interactuar tanto vía TCP como a través de Websockets.</p>



<p>Este enfoque práctico te ayudará a comprender en profundidad cómo garantizar la seguridad en la comunicación MQTT implementando certificados tanto en el servidor como en los clientes. ¡Comencemos!</p>



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



<p>Para el desarrollo de este post se asumen los siguientes puntos:</p>



<ul class="wp-block-list">
<li><strong>PKI y easy-rsa:</strong> Contamos con los conocimientos básicos sobre la gestión de certificados mediante una PKI, tal como se describe en el post <em><a href="https://oriolrius.cat/?p=12824" data-type="link" data-id="https://oriolrius.cat/?p=12824">Gestión de certificados (PKI) &#8211; easy-rsa</a></em>. Se asume que la PKI ya está desplegada siguiendo las indicaciones de dicho post y que la configuración se encuentra en el fichero <code>vars</code>.</li>



<li><strong>Resolución DNS:</strong> Se dispone de un servidor DNS que resuelve los nombres de host dentro de nuestra red privada. Aunque es posible modificar el fichero <code>/etc/hosts</code> para lograrlo, esta práctica se considera menos recomendable en entornos donde se puede optar por una solución DNS adecuada.</li>



<li><strong>Instalación de Mosquitto:</strong> Se asume que Mosquitto y sus herramientas/clients están instalados en el sistema operativo que utilizaremos. En este post, todas las demostraciones se llevarán a cabo en Linux Ubuntu 22.04.</li>
</ul>



<p>Estas asunciones nos permitirán centrarnos en la configuración y uso de certificados en el bróker MQTT sin tener que detallar cada uno de los pasos previos para la creación y administración de la infraestructura de certificados.</p>



<h2 class="wp-block-heading">Demostración en vídeo</h2>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="MQTT Broker (Mosquitto) con certificado servidor (self-signed) y certificado en los clientes" width="1200" height="675" src="https://www.youtube.com/embed/hwH8RiMnlko?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">Obtención de los certificados</h2>



<p>Partimos de lo descrito en el post:  <a href="https://oriolrius.cat/?p=12844" data-type="link" data-id="https://oriolrius.cat/?p=12844">MQTT Broker (Mosquitto) con certificado servidor (self-signed)</a></p>



<p>Por lo tanto, solo tenemos que crear el certificado para los clientes que vamos a usar. Los del servidor MQTT ya están listos.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# desde la máquina que queramos con easy-rsa instalado
./easyrsa gen-req client.example.tld
# se genera fichero mqtt.example.tld.req" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># desde la máquina que queramos con easy-rsa instalado</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">gen-req</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">client.example.tld</span></span>
<span class="line"><span style="color: #616E88"># se genera fichero mqtt.example.tld.req</span></span></code></pre></div>



<h3 class="wp-block-heading">Firma de la petición de certificado</h3>



<p>Si no se lanzó la petición de certificado (<em>certificate request</em>) desde el mismo PKI, hay que copiarlo a la máquina del PKI e importarlo. No lo olvidemos. Aunque en soluciones domésticas típicamente todo lo movemos dentro de la misma estructura de directorios de la PKI.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# en la PKI:
## importamos el certificado, si no se ha hecho la petición desde aquí
## se asume que se copió el fichero de certificate request en
## /the-path/client.example.tld.req
./easyrsa import-req /the-path/client.example.tld.req client.example.tld
## esto colocará una copia del fichero .req en la PKI y algunos enlaces.

## Se le pide a la PKI que firme el certificado
./easyrsa sign-req client client.example.tld
### esto generará el fichero .crt necesarios para armar el cliente." style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># en la PKI:</span></span>
<span class="line"><span style="color: #616E88">## importamos el certificado, si no se ha hecho la petición desde aquí</span></span>
<span class="line"><span style="color: #616E88">## se asume que se copió el fichero de certificate request en</span></span>
<span class="line"><span style="color: #616E88">## /the-path/client.example.tld.req</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">import-req</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/the-path/client.example.tld.req</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">client.example.tld</span></span>
<span class="line"><span style="color: #616E88">## esto colocará una copia del fichero .req en la PKI y algunos enlaces.</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88">## Se le pide a la PKI que firme el certificado</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sign-req</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">client</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">client.example.tld</span></span>
<span class="line"><span style="color: #616E88">### esto generará el fichero .crt necesarios para armar el cliente.</span></span></code></pre></div>



<h3 class="wp-block-heading">Creación y firma de la petición de certificado</h3>



<p>En un solo comando, en el caso de hacerlo todo desde la PKI (en un solo servidor) podemos obtener: clave privada, request de certificador y certificado firmado. Este certificado será de tipo cliente.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="./easyrsa build-client-full client.example.tld

# sin cifrado de la clave privada:
./easyrsa build-client-full client.example.tld --no-pass" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">build-client-full</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">client.example.tld</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># sin cifrado de la clave privada:</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">build-client-full</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">client.example.tld</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--no-pass</span></span></code></pre></div>



<p><strong>IMPORTANTE</strong>, no tiene sentido hacer este comando si previamente hemos hecho la creación de request, (importación) y firmado.</p>



<p>Si queremos emitir un certificado que sea útil tanto para cliente como para servidor podemos usar:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="./easyrsa build-serverClient-full clientserver.example.tld

# sin cifrado de la clave privada:
./easyrsa build-serverClient-full clientserver.example.tld --no-pass" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">build-serverClient-full</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">clientserver.example.tld</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># sin cifrado de la clave privada:</span></span>
<span class="line"><span style="color: #88C0D0">./easyrsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">build-serverClient-full</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">clientserver.example.tld</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--no-pass</span></span></code></pre></div>



<h2 class="wp-block-heading">Configuración de Mosquitto con certificado servidor y requisito de certificado cliente</h2>



<p>Esta configuración es muy sencilla y solo pondrá en marcha un Mosquitto en el puerto TCP/8883 además del puerto WSS/8884. </p>



<p><code>mosquitto.conf</code></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# mqtt secure
listener 8883 0.0.0.0
cafile certs/ca.crt
keyfile certs/mqtt.example.tld.key
certfile certs/mqtt.example.tld.crt
crlfile certs/pki.example.tld.crl
allow_anonymous true
require_certificate true

# websockets secure
listener 8884 0.0.0.0
protocol websockets
cafile certs/ca.crt
keyfile certs/mqtt.example.tld.key
certfile certs/mqtt.example.tld.crt
crlfile certs/pki.example.tld.crl
require_certificate true" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># mqtt secure</span></span>
<span class="line"><span style="color: #88C0D0">listener</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8883</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">.0.0</span></span>
<span class="line"><span style="color: #88C0D0">cafile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/ca.crt</span></span>
<span class="line"><span style="color: #88C0D0">keyfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/mqtt.example.tld.key</span></span>
<span class="line"><span style="color: #88C0D0">certfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/mqtt.example.tld.crt</span></span>
<span class="line"><span style="color: #88C0D0">crlfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/pki.example.tld.crl</span></span>
<span class="line"><span style="color: #88C0D0">allow_anonymous</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span></span>
<span class="line"><span style="color: #88C0D0">require_certificate</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># websockets secure</span></span>
<span class="line"><span style="color: #88C0D0">listener</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8884</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0.0</span><span style="color: #A3BE8C">.0.0</span></span>
<span class="line"><span style="color: #88C0D0">protocol</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">websockets</span></span>
<span class="line"><span style="color: #88C0D0">cafile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/ca.crt</span></span>
<span class="line"><span style="color: #88C0D0">keyfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/mqtt.example.tld.key</span></span>
<span class="line"><span style="color: #88C0D0">certfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/mqtt.example.tld.crt</span></span>
<span class="line"><span style="color: #88C0D0">crlfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/pki.example.tld.crl</span></span>
<span class="line"><span style="color: #88C0D0">require_certificate</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span></span></code></pre></div>



<p>Para lanzar el servicio, simplemente debemos usar el comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="mosquitto -c mosquitto.conf" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">mosquitto</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-c</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mosquitto.conf</span></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Cuando lancemos el servicio se nos pedirá la <em>passphrase</em> de la clave privada dos veces, una para cada uno de los <em>listerners</em> que hemos puesto la configuración, el TCP y el WSS.</p>
</blockquote>



<p>Por otro lado, si se configura <code>use_subject_as_username </code>en <code>true</code>, se empleará el campo completo del sujeto del certificado como nombre de usuario. En el caso de que <code>use_identity_as_username</code> o <code>use_subject_as_username</code> se encuentren desactivados, el cliente deberá autenticarse mediante los métodos habituales, como la verificación a través de <code>password_file</code>. Asimismo, cualquier certificado expedido por las autoridades indicadas en <code>cafile</code> o <code>capath</code> será considerado válido para la conexión, lo que ofrece una mayor flexibilidad en la emisión y comprobación de los certificados de cliente.</p>



<p>Cuando el parámetro <code>require_certificate</code> de Mosquitto está configurado a <code>true</code>, se exige que el cliente presente un certificado válido para poder conectarse satisfactoriamente al servicio MQTT. En este contexto, los parámetros adicionales <code>use_identity_as_username </code>y <code>use_subject_as_username </code>resultan relevantes: si <code>use_identity_as_username </code>se establece en <code>true</code>, se utilizará el Common Name (CN) extraído del certificado del cliente en lugar del nombre de usuario MQTT para el control de acceso, omitiéndose la contraseña, ya que se asume que únicamente los clientes autenticados disponen de certificados válidos.</p>



<h2 class="wp-block-heading">Negociación de la conexión (OpenSSL s_client)</h2>



<p></p>



<p>OpenSSL es la herramienta que hay por debajo de <code>easy-rsa</code> y la librería de referencia para SSL/TLS; además de disponer de herramientas que nos permitirán depurar enlaces de cifrados. Para este caso de uso usaremos <code>openssl s_client</code> que nos va a permitir ver todos los detalles de la negociación SSL/TLS con el servidor de MQTT.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# self-signed fail chechking
openssl s_client \
  -CAfile certs/ca.crt \
  mqtt.example.tld:8883
  
# using my CA, self-signed succesful checking
openssl s_client \
  -CAfile certs/ca.crt \
  --cert certs/client.example.tld.crt \
  --key certs/client.example.tld.key \
  mqtt.example.tld:8883" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># self-signed fail chechking</span></span>
<span class="line"><span style="color: #88C0D0">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">s_client</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">-CAfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/ca.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">mqtt.example.tld:8883</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span></span>
<span class="line"><span style="color: #616E88"># using my CA, self-signed succesful checking</span></span>
<span class="line"><span style="color: #88C0D0">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">s_client</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">-CAfile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/ca.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--cert</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/client.example.tld.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/client.example.tld.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">mqtt.example.tld:8883</span></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>En el vídeo de demostración puedes ver más detalles de cómo se analiza la negociación entre el servidor y el cliente.</p>
</blockquote>



<h2 class="wp-block-heading">Clientes Mosquitto</h2>



<p>Usando <code>mosquitto_sub</code> y <code>mosquitto_pub</code> se demuestra cómo se intercambia tráfico a través de un enlace cifrado. Nada del otro mundo, pero que en entornos cifrados y para evoluciones de este escenario veremos que tiene algunas limitaciones.</p>



<p>Me suscribo al <em>topic</em> llamado <code>topic1</code> y esperando que se publiquen mensajes en él:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="mosquitto_sub -d \
  --cafile pki/ca.crt \
  --cert certs/client.example.tld.crt \
  --key certs/client.example.tld.key \
  -h mqtt.example.tld -p 8883 \
  -t topic1 -v" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">mosquitto_sub</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-d</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--cafile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pki/ca.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--cert</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/client.example.tld.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/client.example.tld.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">-h</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt.example.tld</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8883</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">-t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">topic1</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-v</span></span></code></pre></div>



<p>Publico un mensaje en el topic con el contenido: <code>value</code>1</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="mosquitto_pub -d \
  --cafile pki/ca.crt \
  --cert certs/client.example.tld.crt \
  --key certs/client.example.tld.key \
  -h mqtt.example.tld -p 8883 \
  -t topic1 -m &quot;message1&quot;" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">mosquitto_pub</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-d</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--cafile</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pki/ca.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--cert</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/client.example.tld.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">--key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">certs/client.example.tld.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">-h</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt.example.tld</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8883</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">-t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">topic1</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-m</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">message1</span><span style="color: #ECEFF4">&quot;</span></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p>Cuando lancemos los comandos, se nos pedirá la <em>passphrase</em> de la clave privada. Tanto para publicar como para suscribirnos, ya que ambos necesitan acceso al fichero &#8220;certs/client.example.tld.key&#8221; que esta cifrado con una clave simétrica.</p>
</blockquote>



<h2 class="wp-block-heading">Clientes desarrollados en Python</h2>



<p>Se trata de un par de <em>scripts</em> muy sencillos que solo pretenden ilustrar lo sencillo que es especificar nuestra propia CA en la inicialización de la conexión segura con el servidor MQTT.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# se requiere uv, si no lo tienes instalado:
curl -LsSf https://astral.sh/uv/install.sh | sh
# lanzamos el suscriptor
uv run mqtt_sub.py
# lanzamos el publicador
uv run mqtt_pub.py" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># se requiere uv, si no lo tienes instalado:</span></span>
<span class="line"><span style="color: #88C0D0">curl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-LsSf</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">https://astral.sh/uv/install.sh</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">|</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">sh</span></span>
<span class="line"><span style="color: #616E88"># lanzamos el suscriptor</span></span>
<span class="line"><span style="color: #88C0D0">uv</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt_sub.py</span></span>
<span class="line"><span style="color: #616E88"># lanzamos el publicador</span></span>
<span class="line"><span style="color: #88C0D0">uv</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">run</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt_pub.py</span></span></code></pre></div>



<h2 class="wp-block-heading">Clientes MQTTX-cli usando TCP y Websockets</h2>



<p>Al lanzar el bróker de MQTT expusimos el endpoint en TCP y el de Websockets, pero no hemos usado el segundo para nada todavía. Así, pues, vamos a aprovechar la potencia del cliente de EMQ llamado MQTTX para repetir las mismas funciones que antes, pero ahora haciendo la suscripción con Websockets y la publicación con TCP.</p>



<p>Este cliente por el moment no soporta protección de cifrado simétrico en la clave privada, así pues primero debemos extraer la clave privada a un nuevo fichero:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span role="button" tabindex="0" data-code="# extraer clave privada de fichero cifrado:
openssl rsa -in python_client/certs/client.example.tld.key -out python_client/certs/client.example.tld.key.raw
# para completar el proceso se deberá introducir la clave simétrica


# mqttx-cli using docker
alias mqttx-cli 'docker run --rm \
  --entrypoint /usr/local/bin/mqttx \
  -v ./pki/ca.crt:/tmp/ca.crt \
  -v ./python_client/certs/client.example.tld.crt:/tmp/client.example.tld.crt \
  -v ./python_client/certs/client.example.tld.key.raw:/tmp/client.example.tld.key \
  emqx/mqttx-cli'
  
# suscripción
mqttx-cli sub \
    --ca /tmp/ca.crt \
    --cert /tmp/client.example.tld.crt \
    --key /tmp/client.example.tld.key \
    -h mqtt.example.tld \
    -p 8884 -l wss \
    -t topic1

# publicación
mqttx-cli pub \
    --ca /tmp/ca.crt \
    --cert /tmp/client.example.tld.crt \
    --key /tmp/client.example.tld.key \
    -h mqtt.example.tld \
    -p 8883 -l mqtts \
    -t topic1 -m message1" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># extraer clave privada de fichero cifrado:</span></span>
<span class="line"><span style="color: #88C0D0">openssl</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">rsa</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-in</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">python_client/certs/client.example.tld.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-out</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">python_client/certs/client.example.tld.key.raw</span></span>
<span class="line"><span style="color: #616E88"># para completar el proceso se deberá introducir la clave simétrica</span></span>
<span class="line"></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># mqttx-cli using docker</span></span>
<span class="line"><span style="color: #88C0D0">alias</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqttx-cli</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">docker run --rm \</span></span>
<span class="line"><span style="color: #A3BE8C">  --entrypoint /usr/local/bin/mqttx \</span></span>
<span class="line"><span style="color: #A3BE8C">  -v ./pki/ca.crt:/tmp/ca.crt \</span></span>
<span class="line"><span style="color: #A3BE8C">  -v ./python_client/certs/client.example.tld.crt:/tmp/client.example.tld.crt \</span></span>
<span class="line"><span style="color: #A3BE8C">  -v ./python_client/certs/client.example.tld.key.raw:/tmp/client.example.tld.key \</span></span>
<span class="line"><span style="color: #A3BE8C">  emqx/mqttx-cli</span><span style="color: #ECEFF4">&#39;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span></span>
<span class="line"><span style="color: #616E88"># suscripción</span></span>
<span class="line"><span style="color: #88C0D0">mqttx-cli</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">sub</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">--ca</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/tmp/ca.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">--cert</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/tmp/client.example.tld.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">--key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/tmp/client.example.tld.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">-h</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt.example.tld</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">-p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8884</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-l</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">wss</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">-t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">topic1</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># publicación</span></span>
<span class="line"><span style="color: #88C0D0">mqttx-cli</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">pub</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">--ca</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/tmp/ca.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">--cert</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/tmp/client.example.tld.crt</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">--key</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">/tmp/client.example.tld.key</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">-h</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtt.example.tld</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">-p</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8883</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-l</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mqtts</span><span style="color: #D8DEE9FF"> </span><span style="color: #EBCB8B">\</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #A3BE8C">-t</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">topic1</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-m</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">message1</span></span></code></pre></div>



<p></p>



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



<ul class="wp-block-list">
<li>Repositorio: <a href="https://github.com/oriolrius/mqtt-server-n-client-n-server-private-pki">github.com/mqtt-server-n-client-n-server-private-pki</a></li>



<li>Repositorio: <a href="https://github.com/oriolrius/mqtt-server-private-pki">github.com/mqtt-server-private-pki</a></li>



<li><a href="https://mqttx.app/">https://mqttx.app/</a></li>



<li><a href="https://mqttx.app/docs/cli">https://mqttx.app/docs/cli</a></li>



<li><a href="http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/" data-type="link" data-id="http://www.steves-internet-guide.com/creating-and-using-client-certificates-with-mqtt-and-mosquitto/">Creating and Using Client Certificates with MQTT and Mosquitto</a></li>



<li><a href="http://www.steves-internet-guide.com/using-lets-encrypt-certificate-mosquitto/" data-type="link" data-id="http://www.steves-internet-guide.com/using-lets-encrypt-certificate-mosquitto/">Using A Lets Encrypt Certificate on Mosquitto</a></li>



<li><a href="http://www.steves-internet-guide.com/ssl-certificates-explained/" data-type="link" data-id="http://www.steves-internet-guide.com/ssl-certificates-explained/">SSL and SSL Certificates Explained For Beginners</a></li>



<li><a href="https://mosquitto.org/man/mosquitto-conf-5.html" data-type="link" data-id="https://mosquitto.org/man/mosquitto-conf-5.html">Mosquitto.conf man</a></li>



<li><a href="https://cedalo.com/blog/enabling-websockets-over-mqtt-with-mosquitto/" data-type="link" data-id="https://cedalo.com/blog/enabling-websockets-over-mqtt-with-mosquitto/">How to Configure MQTT over WebSockets with Mosquitto Broker</a></li>



<li><a href="https://www.emqx.com/en/blog/getting-the-clients-real-ip-when-using-the-nginx-reverse-proxy-emqx#getting-the-mqtt-over-websocket-client-s-real-ip" data-type="link" data-id="https://www.emqx.com/en/blog/getting-the-clients-real-ip-when-using-the-nginx-reverse-proxy-emqx#getting-the-mqtt-over-websocket-client-s-real-ip">Getting the Client&#8217;s Real IP When Using the NGINX Reverse Proxy for EMQX</a></li>
</ul>



<p></p>
		</div>
				</article>
				</div>
		
				<div class="e-load-more-anchor" data-page="1" data-max-page="300" data-next-page="https://oriolrius.cat/page/2/"></div>
				<nav class="elementor-pagination" aria-label="Pagination">
			<span class="page-numbers prev">&laquo; Anterior</span>
<span aria-current="page" class="page-numbers current"><span class="elementor-screen-only">Page</span>1</span>
<a class="page-numbers" href="https://oriolrius.cat/page/2/"><span class="elementor-screen-only">Page</span>2</a>
<a class="page-numbers" href="https://oriolrius.cat/page/3/"><span class="elementor-screen-only">Page</span>3</a>
<span class="page-numbers dots">&hellip;</span>
<a class="page-numbers" href="https://oriolrius.cat/page/300/"><span class="elementor-screen-only">Page</span>300</a>
<a class="page-numbers next" href="https://oriolrius.cat/page/2/">Siguiente &raquo;</a>		</nav>
						</div>
				</div>
					</div>
		</div>
					</div>
		</section>
				</div>
		
	
	
</div><!-- .entry-content .clear -->

	
	
</article><!-- #post-## -->

			</main><!-- #main -->
			
		
	</div><!-- #primary -->


	</div> <!-- ast-container -->
	</div><!-- #content -->
		<footer data-elementor-type="footer" data-elementor-id="9624" class="elementor elementor-9624 elementor-location-footer" data-elementor-post-type="elementor_library">
					<footer data-particle_enable="false" data-particle-mobile-disabled="false" class="elementor-section elementor-top-section elementor-element elementor-element-37b0f69 elementor-section-content-middle elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="37b0f69" data-element_type="section" data-e-type="section" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}">
						<div class="elementor-container elementor-column-gap-default">
					<div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-5b761e37" data-id="5b761e37" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<section data-particle_enable="false" data-particle-mobile-disabled="false" class="elementor-section elementor-inner-section elementor-element elementor-element-7e3e0e4 elementor-section-content-middle elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="7e3e0e4" data-element_type="section" data-e-type="section">
						<div class="elementor-container elementor-column-gap-default">
					<div class="elementor-column elementor-col-50 elementor-inner-column elementor-element elementor-element-34a3e44" data-id="34a3e44" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<div class="elementor-element elementor-element-c7607b1 elementor-shape-circle e-grid-align-left elementor-grid-0 elementor-widget elementor-widget-global elementor-global-9678 elementor-widget-social-icons" data-id="c7607b1" data-element_type="widget" data-e-type="widget" data-widget_type="social-icons.default">
				<div class="elementor-widget-container">
							<div class="elementor-social-icons-wrapper elementor-grid" role="list">
							<span class="elementor-grid-item" role="listitem">
					<a class="elementor-icon elementor-social-icon elementor-social-icon-linkedin elementor-repeater-item-7868ce3" href="https://www.linkedin.com/in/oriolrius" target="_blank">
						<span class="elementor-screen-only">Linkedin</span>
						<i aria-hidden="true" class="fab fa-linkedin"></i>					</a>
				</span>
							<span class="elementor-grid-item" role="listitem">
					<a class="elementor-icon elementor-social-icon elementor-social-icon-youtube elementor-repeater-item-2117248" href="https://www.youtube.com/user/oriolrius" target="_blank">
						<span class="elementor-screen-only">Youtube</span>
						<i aria-hidden="true" class="fab fa-youtube"></i>					</a>
				</span>
					</div>
						</div>
				</div>
					</div>
		</div>
				<div class="elementor-column elementor-col-50 elementor-inner-column elementor-element elementor-element-eac0bef" data-id="eac0bef" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<div class="elementor-element elementor-element-1acf7fc elementor-widget elementor-widget-image" data-id="1acf7fc" data-element_type="widget" data-e-type="widget" data-widget_type="image.default">
				<div class="elementor-widget-container">
																<a href="https://oriolrius.me/">
							<img width="525" height="162" src="https://oriolrius.cat/wp-content/uploads/2023/04/logo_v5.png" class="attachment-large size-large wp-image-11089" alt="" srcset="https://oriolrius.cat/wp-content/uploads/2023/04/logo_v5.png 525w, https://oriolrius.cat/wp-content/uploads/2023/04/logo_v5-400x123.png 400w" sizes="(max-width: 525px) 100vw, 525px" />								</a>
															</div>
				</div>
					</div>
		</div>
					</div>
		</section>
				<section data-particle_enable="false" data-particle-mobile-disabled="false" class="elementor-section elementor-inner-section elementor-element elementor-element-36832e0b elementor-section-content-middle elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="36832e0b" data-element_type="section" data-e-type="section">
						<div class="elementor-container elementor-column-gap-default">
					<div class="elementor-column elementor-col-100 elementor-inner-column elementor-element elementor-element-70f18319" data-id="70f18319" data-element_type="column" data-e-type="column">
			<div class="elementor-widget-wrap elementor-element-populated">
						<div class="elementor-element elementor-element-79396bd2 elementor-widget elementor-widget-heading" data-id="79396bd2" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
					<p class="elementor-heading-title elementor-size-default">© 2026 Oriol Rius</p>				</div>
				</div>
				<div class="elementor-element elementor-element-ba1b816 elementor-widget elementor-widget-heading" data-id="ba1b816" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
					<p class="elementor-heading-title elementor-size-default"><a href="https://creativecommons.org/licenses/by-sa/2.5/es/">Creative Commons Attribution-Share Alike 2.5 Spain License.</a></p>				</div>
				</div>
				<div class="elementor-element elementor-element-76561a3 elementor-widget elementor-widget-heading" data-id="76561a3" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
					<p class="elementor-heading-title elementor-size-default"><a href="https://oriolrius.cat/wp-page/politica-de-privacidad/">Aviso Legal y Política de Privacidad</a></p>				</div>
				</div>
				<div class="elementor-element elementor-element-5a97135 elementor-widget elementor-widget-heading" data-id="5a97135" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
					<p class="elementor-heading-title elementor-size-default"><a href="https://oriolrius.cat/sitemap_index.xml">Mapa del sitio</a></p>				</div>
				</div>
				<div class="elementor-element elementor-element-b0b3563 elementor-widget elementor-widget-heading" data-id="b0b3563" data-element_type="widget" data-e-type="widget" data-widget_type="heading.default">
				<div class="elementor-widget-container">
					<p class="elementor-heading-title elementor-size-default"><a href="https://oriolrius.cat/wp-page/declaracion-de-accesibilidad/">Declaración de accesibilidad</a></p>				</div>
				</div>
					</div>
		</div>
					</div>
		</section>
					</div>
		</div>
					</div>
		</footer>
				</footer>
			</div><!-- #page -->
<script type="speculationrules">
{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/astra/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]}
</script>

<div id="ast-scroll-top" tabindex="0" class="ast-scroll-top-icon ast-scroll-to-top-right" data-on-devices="both">
	<span class="ast-icon icon-arrow"><svg class="ast-arrow-svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" x="0px" y="0px" width="26px" height="16.043px" viewBox="57 35.171 26 16.043" enable-background="new 57 35.171 26 16.043" xml:space="preserve">
                <path d="M57.5,38.193l12.5,12.5l12.5-12.5l-2.5-2.5l-10,10l-10-10L57.5,38.193z" />
                </svg></span>	<span class="screen-reader-text">Scroll to Top</span>
</div>
			<script>
				const lazyloadRunObserver = () => {
					const lazyloadBackgrounds = document.querySelectorAll( `.e-con.e-parent:not(.e-lazyloaded)` );
					const lazyloadBackgroundObserver = new IntersectionObserver( ( entries ) => {
						entries.forEach( ( entry ) => {
							if ( entry.isIntersecting ) {
								let lazyloadBackground = entry.target;
								if( lazyloadBackground ) {
									lazyloadBackground.classList.add( 'e-lazyloaded' );
								}
								lazyloadBackgroundObserver.unobserve( entry.target );
							}
						});
					}, { rootMargin: '200px 0px 200px 0px' } );
					lazyloadBackgrounds.forEach( ( lazyloadBackground ) => {
						lazyloadBackgroundObserver.observe( lazyloadBackground );
					} );
				};
				const events = [
					'DOMContentLoaded',
					'elementor/lazyload/observe',
				];
				events.forEach( ( event ) => {
					document.addEventListener( event, lazyloadRunObserver );
				} );
			</script>
			<script id="astra-theme-js-js-extra">
var astra = {"break_point":"921","isRtl":"","is_scroll_to_id":"1","is_scroll_to_top":"1","is_header_footer_builder_active":"1","responsive_cart_click":"flyout","is_dark_palette":""};
//# sourceURL=astra-theme-js-js-extra
</script>
<script src="https://oriolrius.cat/wp-content/themes/astra/assets/js/minified/frontend.min.js?ver=4.13.3" id="astra-theme-js-js"></script>
<script id="astra-addon-js-js-extra">
var astraAddon = {"is_elementor_active":"1","sticky_active":"","svgIconClose":"\u003Cspan class=\"ast-icon icon-close\"\u003E\u003Csvg viewBox=\"0 0 512 512\" aria-hidden=\"true\" role=\"img\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"18px\" height=\"18px\"\u003E\n                                \u003Cpath d=\"M71.029 71.029c9.373-9.372 24.569-9.372 33.942 0L256 222.059l151.029-151.03c9.373-9.372 24.569-9.372 33.942 0 9.372 9.373 9.372 24.569 0 33.942L289.941 256l151.03 151.029c9.372 9.373 9.372 24.569 0 33.942-9.373 9.372-24.569 9.372-33.942 0L256 289.941l-151.029 151.03c-9.373 9.372-24.569 9.372-33.942 0-9.372-9.373-9.372-24.569 0-33.942L222.059 256 71.029 104.971c-9.372-9.373-9.372-24.569 0-33.942z\" /\u003E\n                            \u003C/svg\u003E\u003C/span\u003E","hf_account_show_menu_on":"hover","hf_account_action_type":"link","hf_account_logout_action":"link","is_header_builder_active":"1"};
//# sourceURL=astra-addon-js-js-extra
</script>
<script src="https://oriolrius.cat/wp-content/uploads/astra-addon/astra-addon-6a1d6d359a65c1-17854826.js?ver=4.13.3" id="astra-addon-js-js"></script>
<script src="https://oriolrius.cat/wp-content/plugins/astra-addon/assets/js/minified/purify.min.js?ver=4.13.3" id="astra-dom-purify-js"></script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor/assets/js/webpack.runtime.min.js?ver=4.1.1" id="elementor-webpack-runtime-js"></script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor/assets/js/frontend-modules.min.js?ver=4.1.1" id="elementor-frontend-modules-js"></script>
<script src="https://oriolrius.cat/wp-includes/js/jquery/ui/core.min.js?ver=1.13.3" id="jquery-ui-core-js"></script>
<script id="elementor-frontend-js-extra">
var EAELImageMaskingConfig = {"svg_dir_url":"https://oriolrius.cat/wp-content/plugins/essential-addons-for-elementor-lite/assets/front-end/img/image-masking/svg-shapes/"};
//# sourceURL=elementor-frontend-js-extra
</script>
<script id="elementor-frontend-js-before">
var elementorFrontendConfig = {"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Share on Facebook","shareOnTwitter":"Share on Twitter","pinIt":"Pin it","download":"Download","downloadImage":"Download image","fullscreen":"Fullscreen","zoom":"Zoom","share":"Share","playVideo":"Play Video","previous":"Previous","next":"Next","close":"Close","a11yCarouselPrevSlideMessage":"Previous slide","a11yCarouselNextSlideMessage":"Next slide","a11yCarouselFirstSlideMessage":"This is the first slide","a11yCarouselLastSlideMessage":"This is the last slide","a11yCarouselPaginationBulletMessage":"Go to slide"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}},"hasCustomBreakpoints":false},"version":"4.1.1","is_static":false,"experimentalFeatures":{"additional_custom_breakpoints":true,"theme_builder_v2":true,"global_classes_should_enforce_capabilities":true,"e_variables":true,"e_opt_in_v4_page":true,"e_components":true,"e_interactions":true,"e_widget_creation":true,"import-export-customization":true,"e_pro_atomic_form":true,"e_pro_variables":true,"e_pro_interactions":true},"urls":{"assets":"https:\/\/oriolrius.cat\/wp-content\/plugins\/elementor\/assets\/","ajaxurl":"https:\/\/oriolrius.cat\/wp-admin\/admin-ajax.php","uploadUrl":"https:\/\/oriolrius.cat\/wp-content\/uploads"},"nonces":{"floatingButtonsClickTracking":"2bcfc1126e","atomicFormsSendForm":"81a1c2a075"},"swiperClass":"swiper","settings":{"page":[],"editorPreferences":[]},"kit":{"active_breakpoints":["viewport_mobile","viewport_tablet"],"global_image_lightbox":"yes","lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description"},"post":{"id":9608,"title":"oriolrius.cat%20%E2%80%93%20Oriol%20Rius%20%3A%3A%20Technology%20%3A%20Crecimiento%20Personal%20%3A%20Mussol","excerpt":"","featuredImage":"https:\/\/oriolrius.cat\/wp-content\/uploads\/2023\/04\/screenshot-oriolrius.cat-2023.04.25-16_04_26.png"}};
//# sourceURL=elementor-frontend-js-before
</script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor/assets/js/frontend.min.js?ver=4.1.1" id="elementor-frontend-js"></script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/lib/smartmenus/jquery.smartmenus.min.js?ver=1.2.1" id="smartmenus-js"></script>
<script src="https://oriolrius.cat/wp-includes/js/imagesloaded.min.js?ver=5.0.0" id="imagesloaded-js"></script>
<script id="eael-general-js-extra">
var localize = {"ajaxurl":"https://oriolrius.cat/wp-admin/admin-ajax.php","nonce":"93cfe3165e","i18n":{"added":"Added ","compare":"Compare","loading":"Loading..."},"eael_translate_text":{"required_text":"is a required field","invalid_text":"Invalid","billing_text":"Billing","shipping_text":"Shipping","fg_mfp_counter_text":"of"},"page_permalink":"https://oriolrius.cat/","cart_redirectition":"","cart_page_url":"","el_breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}},"ParticleThemesData":{"default":"{\"particles\":{\"number\":{\"value\":160,\"density\":{\"enable\":true,\"value_area\":800}},\"color\":{\"value\":\"#ffffff\"},\"shape\":{\"type\":\"circle\",\"stroke\":{\"width\":0,\"color\":\"#000000\"},\"polygon\":{\"nb_sides\":5},\"image\":{\"src\":\"img/github.svg\",\"width\":100,\"height\":100}},\"opacity\":{\"value\":0.5,\"random\":false,\"anim\":{\"enable\":false,\"speed\":1,\"opacity_min\":0.1,\"sync\":false}},\"size\":{\"value\":3,\"random\":true,\"anim\":{\"enable\":false,\"speed\":40,\"size_min\":0.1,\"sync\":false}},\"line_linked\":{\"enable\":true,\"distance\":150,\"color\":\"#ffffff\",\"opacity\":0.4,\"width\":1},\"move\":{\"enable\":true,\"speed\":6,\"direction\":\"none\",\"random\":false,\"straight\":false,\"out_mode\":\"out\",\"bounce\":false,\"attract\":{\"enable\":false,\"rotateX\":600,\"rotateY\":1200}}},\"interactivity\":{\"detect_on\":\"canvas\",\"events\":{\"onhover\":{\"enable\":true,\"mode\":\"repulse\"},\"onclick\":{\"enable\":true,\"mode\":\"push\"},\"resize\":true},\"modes\":{\"grab\":{\"distance\":400,\"line_linked\":{\"opacity\":1}},\"bubble\":{\"distance\":400,\"size\":40,\"duration\":2,\"opacity\":8,\"speed\":3},\"repulse\":{\"distance\":200,\"duration\":0.4},\"push\":{\"particles_nb\":4},\"remove\":{\"particles_nb\":2}}},\"retina_detect\":true}","nasa":"{\"particles\":{\"number\":{\"value\":250,\"density\":{\"enable\":true,\"value_area\":800}},\"color\":{\"value\":\"#ffffff\"},\"shape\":{\"type\":\"circle\",\"stroke\":{\"width\":0,\"color\":\"#000000\"},\"polygon\":{\"nb_sides\":5},\"image\":{\"src\":\"img/github.svg\",\"width\":100,\"height\":100}},\"opacity\":{\"value\":1,\"random\":true,\"anim\":{\"enable\":true,\"speed\":1,\"opacity_min\":0,\"sync\":false}},\"size\":{\"value\":3,\"random\":true,\"anim\":{\"enable\":false,\"speed\":4,\"size_min\":0.3,\"sync\":false}},\"line_linked\":{\"enable\":false,\"distance\":150,\"color\":\"#ffffff\",\"opacity\":0.4,\"width\":1},\"move\":{\"enable\":true,\"speed\":1,\"direction\":\"none\",\"random\":true,\"straight\":false,\"out_mode\":\"out\",\"bounce\":false,\"attract\":{\"enable\":false,\"rotateX\":600,\"rotateY\":600}}},\"interactivity\":{\"detect_on\":\"canvas\",\"events\":{\"onhover\":{\"enable\":true,\"mode\":\"bubble\"},\"onclick\":{\"enable\":true,\"mode\":\"repulse\"},\"resize\":true},\"modes\":{\"grab\":{\"distance\":400,\"line_linked\":{\"opacity\":1}},\"bubble\":{\"distance\":250,\"size\":0,\"duration\":2,\"opacity\":0,\"speed\":3},\"repulse\":{\"distance\":400,\"duration\":0.4},\"push\":{\"particles_nb\":4},\"remove\":{\"particles_nb\":2}}},\"retina_detect\":true}","bubble":"{\"particles\":{\"number\":{\"value\":15,\"density\":{\"enable\":true,\"value_area\":800}},\"color\":{\"value\":\"#1b1e34\"},\"shape\":{\"type\":\"polygon\",\"stroke\":{\"width\":0,\"color\":\"#000\"},\"polygon\":{\"nb_sides\":6},\"image\":{\"src\":\"img/github.svg\",\"width\":100,\"height\":100}},\"opacity\":{\"value\":0.3,\"random\":true,\"anim\":{\"enable\":false,\"speed\":1,\"opacity_min\":0.1,\"sync\":false}},\"size\":{\"value\":50,\"random\":false,\"anim\":{\"enable\":true,\"speed\":10,\"size_min\":40,\"sync\":false}},\"line_linked\":{\"enable\":false,\"distance\":200,\"color\":\"#ffffff\",\"opacity\":1,\"width\":2},\"move\":{\"enable\":true,\"speed\":8,\"direction\":\"none\",\"random\":false,\"straight\":false,\"out_mode\":\"out\",\"bounce\":false,\"attract\":{\"enable\":false,\"rotateX\":600,\"rotateY\":1200}}},\"interactivity\":{\"detect_on\":\"canvas\",\"events\":{\"onhover\":{\"enable\":false,\"mode\":\"grab\"},\"onclick\":{\"enable\":false,\"mode\":\"push\"},\"resize\":true},\"modes\":{\"grab\":{\"distance\":400,\"line_linked\":{\"opacity\":1}},\"bubble\":{\"distance\":400,\"size\":40,\"duration\":2,\"opacity\":8,\"speed\":3},\"repulse\":{\"distance\":200,\"duration\":0.4},\"push\":{\"particles_nb\":4},\"remove\":{\"particles_nb\":2}}},\"retina_detect\":true}","snow":"{\"particles\":{\"number\":{\"value\":450,\"density\":{\"enable\":true,\"value_area\":800}},\"color\":{\"value\":\"#fff\"},\"shape\":{\"type\":\"circle\",\"stroke\":{\"width\":0,\"color\":\"#000000\"},\"polygon\":{\"nb_sides\":5},\"image\":{\"src\":\"img/github.svg\",\"width\":100,\"height\":100}},\"opacity\":{\"value\":0.5,\"random\":true,\"anim\":{\"enable\":false,\"speed\":1,\"opacity_min\":0.1,\"sync\":false}},\"size\":{\"value\":5,\"random\":true,\"anim\":{\"enable\":false,\"speed\":40,\"size_min\":0.1,\"sync\":false}},\"line_linked\":{\"enable\":false,\"distance\":500,\"color\":\"#ffffff\",\"opacity\":0.4,\"width\":2},\"move\":{\"enable\":true,\"speed\":6,\"direction\":\"bottom\",\"random\":false,\"straight\":false,\"out_mode\":\"out\",\"bounce\":false,\"attract\":{\"enable\":false,\"rotateX\":600,\"rotateY\":1200}}},\"interactivity\":{\"detect_on\":\"canvas\",\"events\":{\"onhover\":{\"enable\":true,\"mode\":\"bubble\"},\"onclick\":{\"enable\":true,\"mode\":\"repulse\"},\"resize\":true},\"modes\":{\"grab\":{\"distance\":400,\"line_linked\":{\"opacity\":0.5}},\"bubble\":{\"distance\":400,\"size\":4,\"duration\":0.3,\"opacity\":1,\"speed\":3},\"repulse\":{\"distance\":200,\"duration\":0.4},\"push\":{\"particles_nb\":4},\"remove\":{\"particles_nb\":2}}},\"retina_detect\":true}","nyan_cat":"{\"particles\":{\"number\":{\"value\":150,\"density\":{\"enable\":false,\"value_area\":800}},\"color\":{\"value\":\"#ffffff\"},\"shape\":{\"type\":\"star\",\"stroke\":{\"width\":0,\"color\":\"#000000\"},\"polygon\":{\"nb_sides\":5},\"image\":{\"src\":\"http://wiki.lexisnexis.com/academic/images/f/fb/Itunes_podcast_icon_300.jpg\",\"width\":100,\"height\":100}},\"opacity\":{\"value\":0.5,\"random\":false,\"anim\":{\"enable\":false,\"speed\":1,\"opacity_min\":0.1,\"sync\":false}},\"size\":{\"value\":4,\"random\":true,\"anim\":{\"enable\":false,\"speed\":40,\"size_min\":0.1,\"sync\":false}},\"line_linked\":{\"enable\":false,\"distance\":150,\"color\":\"#ffffff\",\"opacity\":0.4,\"width\":1},\"move\":{\"enable\":true,\"speed\":14,\"direction\":\"left\",\"random\":false,\"straight\":true,\"out_mode\":\"out\",\"bounce\":false,\"attract\":{\"enable\":false,\"rotateX\":600,\"rotateY\":1200}}},\"interactivity\":{\"detect_on\":\"canvas\",\"events\":{\"onhover\":{\"enable\":false,\"mode\":\"grab\"},\"onclick\":{\"enable\":true,\"mode\":\"repulse\"},\"resize\":true},\"modes\":{\"grab\":{\"distance\":200,\"line_linked\":{\"opacity\":1}},\"bubble\":{\"distance\":400,\"size\":40,\"duration\":2,\"opacity\":8,\"speed\":3},\"repulse\":{\"distance\":200,\"duration\":0.4},\"push\":{\"particles_nb\":4},\"remove\":{\"particles_nb\":2}}},\"retina_detect\":true}"},"eael_login_nonce":"ef0ba20f7f","eael_register_nonce":"a5bfaaf5ab","eael_lostpassword_nonce":"84d3733619","eael_resetpassword_nonce":"a38cea93c0"};
//# sourceURL=eael-general-js-extra
</script>
<script src="https://oriolrius.cat/wp-content/plugins/essential-addons-for-elementor-lite/assets/front-end/js/view/general.min.js?ver=6.6.5" id="eael-general-js"></script>
<script src="https://oriolrius.cat/wp-content/plugins/code-block-pro/build/front/front.js?ver=897e78bb623a899126f1" id="kevinbatdorf-code-block-pro-view-script-js" data-wp-strategy="defer"></script>
<script id="kevinbatdorf-code-block-pro-view-script-js-after">
window.codeBlockPro = {"pluginUrl":"https:\/\/oriolrius.cat\/wp-content\/plugins\/code-block-pro\/"};
//# sourceURL=kevinbatdorf-code-block-pro-view-script-js-after
</script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/js/webpack-pro.runtime.min.js?ver=4.1.0" id="elementor-pro-webpack-runtime-js"></script>
<script src="https://oriolrius.cat/wp-includes/js/dist/hooks.min.js?ver=dd5603f07f9220ed27f1" id="wp-hooks-js"></script>
<script src="https://oriolrius.cat/wp-includes/js/dist/i18n.min.js?ver=c26c3dc7bed366793375" id="wp-i18n-js"></script>
<script id="wp-i18n-js-after">
wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } );
//# sourceURL=wp-i18n-js-after
</script>
<script id="elementor-pro-frontend-js-before">
var ElementorProFrontendConfig = {"ajaxurl":"https:\/\/oriolrius.cat\/wp-admin\/admin-ajax.php","nonce":"3e3742caa6","urls":{"assets":"https:\/\/oriolrius.cat\/wp-content\/plugins\/elementor-pro\/assets\/","rest":"https:\/\/oriolrius.cat\/wp-json\/"},"settings":{"lazy_load_background_images":true},"popup":{"hasPopUps":false},"shareButtonsNetworks":{"facebook":{"title":"Facebook","has_counter":true},"twitter":{"title":"Twitter"},"linkedin":{"title":"LinkedIn","has_counter":true},"pinterest":{"title":"Pinterest","has_counter":true},"reddit":{"title":"Reddit","has_counter":true},"vk":{"title":"VK","has_counter":true},"odnoklassniki":{"title":"OK","has_counter":true},"tumblr":{"title":"Tumblr"},"digg":{"title":"Digg"},"skype":{"title":"Skype"},"stumbleupon":{"title":"StumbleUpon","has_counter":true},"mix":{"title":"Mix"},"telegram":{"title":"Telegram"},"pocket":{"title":"Pocket","has_counter":true},"xing":{"title":"XING","has_counter":true},"whatsapp":{"title":"WhatsApp"},"email":{"title":"Email"},"print":{"title":"Print"},"x-twitter":{"title":"X"},"threads":{"title":"Threads"}},"facebook_sdk":{"lang":"en_US","app_id":""},"lottie":{"defaultAnimationUrl":"https:\/\/oriolrius.cat\/wp-content\/plugins\/elementor-pro\/modules\/lottie\/assets\/animations\/default.json"}};
//# sourceURL=elementor-pro-frontend-js-before
</script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/js/frontend.min.js?ver=4.1.0" id="elementor-pro-frontend-js"></script>
<script src="https://oriolrius.cat/wp-content/plugins/elementor-pro/assets/js/elements-handlers.min.js?ver=4.1.0" id="pro-elements-handlers-js"></script>
			<script>
			/(trident|msie)/i.test(navigator.userAgent)&&document.getElementById&&window.addEventListener&&window.addEventListener("hashchange",function(){var t,e=location.hash.substring(1);/^[A-z0-9_-]+$/.test(e)&&(t=document.getElementById(e))&&(/^(?:a|select|input|button|textarea)$/i.test(t.tagName)||(t.tabIndex=-1),t.focus())},!1);
			</script>
			<script id="wp-emoji-settings" type="application/json">
{"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://oriolrius.cat/wp-includes/js/wp-emoji-release.min.js?ver=6.9.4"}}
</script>
<script type="module">
/*! This file is auto-generated */
const a=JSON.parse(document.getElementById("wp-emoji-settings").textContent),o=(window._wpemojiSettings=a,"wpEmojiSettingsSupports"),s=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(o,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const a=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===a[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,a){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!a(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,a){let r;const o=(r="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),s=(o.textBaseline="top",o.font="600 32px Arial",{});return e.forEach(e=>{s[e]=t(o,e,n,a)}),s}function r(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}a.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(o));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(s),u.toString(),c.toString(),p.toString()].join(",")+"));",a=new Blob([e],{type:"text/javascript"});const r=new Worker(URL.createObjectURL(a),{name:"wpTestEmojiSupports"});return void(r.onmessage=e=>{i(n=e.data),r.terminate(),t(n)})}catch(e){}i(n=f(s,u,c,p))}t(n)}).then(e=>{for(const n in e)a.supports[n]=e[n],a.supports.everything=a.supports.everything&&a.supports[n],"flag"!==n&&(a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&a.supports[n]);var t;a.supports.everythingExceptFlag=a.supports.everythingExceptFlag&&!a.supports.flag,a.supports.everything||((t=a.source||{}).concatemoji?r(t.concatemoji):t.wpemoji&&t.twemoji&&(r(t.twemoji),r(t.wpemoji)))});
//# sourceURL=https://oriolrius.cat/wp-includes/js/wp-emoji-loader.min.js
</script>
	</body>
</html>
