<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>linuxgemini&#39;s space of text</title>
    <link>https://blog.linuxgemini.space/</link>
    <description>I talk about software and more. Sometimes in English, bazen de Türkçe.</description>
    <pubDate>Thu, 04 Jun 2026 17:33:36 +0000</pubDate>
    <item>
      <title>Putting EJBCA behind a reverse proxy with a trusted TLS certificate</title>
      <link>https://blog.linuxgemini.space/ejbca-with-reverse-proxy</link>
      <description>&lt;![CDATA[So normally you&#39;d deploy EJBCA internally. But what if you wanted to publicly use it for SCEP but not want to deploy the ManagementCA to user trust store?&#xA;&#xA;That&#39;s when you&#39;d put EJBCA behind a reverse proxy, but how?&#xA;&#xA;!--more--&#xA;&#xA;Prerequisites&#xA;&#xA;Prepare your own root CA: You&#39;ll need the keypair as a PKCS#12 file and the root CA certificate itself as a PEM file.&#xA;&#xA;Put the root CA certificate to somewhere the reverse proxy can access. /opt/rootca.pem would be an example. Make sure it is readable by everyone: chmod 644 /opt/rootca.pem&#xA;&#xA;DNS&#xA;&#xA;Make sure you&#39;ve set up a (sub-)domain that points to your EJBCA server. For this blog post, I&#39;ve chosen ejbca.example.com.&#xA;&#xA;Procedure&#xA;&#xA;We&#39;ll go over bootstrapping EJBCA itself and the reverse proxy configuration.&#xA;&#xA;EJBCA&#xA;&#xA;Bring up EJBCA using Keyfactor&#39;s own Docker Compose file with little modifications:&#xA;&#xA;---&#xA;networks:&#xA;  access-bridge:&#xA;    driver: bridge&#xA;  application-bridge:&#xA;    driver: bridge&#xA;services:&#xA;  ejbca-database:&#xA;    containername: ejbca-database&#xA;    image: &#34;library/mariadb:latest&#34;&#xA;    restart: unless-stopped&#xA;    networks:&#xA;      application-bridge&#xA;    environment:&#xA;      MYSQLROOTPASSWORD=foo123&#xA;      MYSQLDATABASE=ejbca&#xA;      MYSQLUSER=ejbca&#xA;      MYSQLPASSWORD=ejbca&#xA;    volumes:&#xA;      ./datadbdir:/var/lib/mysql:rw&#xA;  ejbca:&#xA;    hostname: ejbca-node1&#xA;    containername: ejbca&#xA;    image: keyfactor/ejbca-ce:latest&#xA;    dependson:&#xA;      ejbca-database&#xA;    restart: unless-stopped&#xA;    networks:&#xA;      access-bridge&#xA;      application-bridge&#xA;    environment:&#xA;      DATABASEJDBCURL=jdbc:mariadb://ejbca-database:3306/ejbca?characterEncoding=UTF-8&#xA;      LOGLEVELAPP=INFO&#xA;      LOGLEVELSERVER=INFO&#xA;      TLSSETUPENABLED=later&#xA;      PROXYHTTPBIND=0.0.0.0&#xA;    ports:&#xA;      # Proxy port for the HTTP endpoint (normally 8080 when PROXYHTTPBIND is not set)&#xA;      &#34;127.0.0.1:8081:8081&#34;&#xA;      # Proxy port for the HTTPS endpoint, it is HTTP but has&#xA;      # SSLCLIENTCERT header support to provide the&#xA;      # equivalent of the regular HTTPS endpoint&#xA;      # (normally 8443 when PROXYHTTPBIND is not set)&#xA;      &#34;127.0.0.1:8082:8082&#34;&#xA;&#xA;Aside from the addition of restart: unless-stopped, notice that the environment variables TLSSETUPENABLED is set to later and PROXYHTTPBIND is set to 0.0.0.0. These two makes few changes:&#xA;&#xA;  Disable generation of ManagementCA, you need to provide/generate your own CA.&#xA;  Make Wildfly (the application server) not listen on HTTPS but on two special HTTP proxy ports:&#xA;    8081 for regular HTTP traffic, but with proxy header support&#xA;    8082 for regular HTTPS traffic, but is HTTP with proxy port and SSLCLIENTCERT header support as a way for the reverse proxy to provide the client certificate from an mTLS handshake.&#xA;&#xA;Reverse Proxy&#xA;&#xA;I chose NGINX for this, but you can choose any reverse proxy you want that supports mTLS with a different CA other than the one used for the web service.&#xA;&#xA;Make sure you don&#39;t have any firewall rules blocking the ports 80 and 443.&#xA;&#xA;subiSince I am doing all this in Enterprise Linux, the config file structure is a bit different than the Debian packaging; so be wary./i/sub&#xA;&#xA;After install, make a copy of /etc/nginx/nginx.conf to a temporary place, you&#39;re going to use it later on: cp -a /etc/nginx/nginx.conf /tmp/nginxprebootstrap.conf&#xA;&#xA;Bootstrapping TLS with certbot&#xA;&#xA;Set the servername variable in the /etc/nginx/nginx.conf file to the (sub-)domain you&#39;ve chosen.&#xA;&#xA;Make sure to have the EPEL repository installed and enabled. Install certbot and its NGINX plugin (dnf install certbot python3-certbot-nginx).&#xA;&#xA;Register your ACME account: certbot register --email youremail@example.com --no-eff-email --agree-tos&#xA;&#xA;Obtain your TLS certificate and install it into NGINX automatically: certbot --nginx --domains ejbca.example.com --key-type rsa&#xA;&#xA;Re-configuring NGINX&#xA;&#xA;Copy back the config file from earlier: cp -af /tmp/nginxprebootstrap.conf /etc/nginx/nginx.conf&#xA;&#xA;Comment out the default server block that&#39;s below the line include /etc/nginx/conf.d/.conf; in /etc/nginx/nginx.conf. It should look like this:&#xA;&#xA;A terminal screenshot showing the nano editor with the NGINX configuration being open.&#xA;&#xA;We&#39;re going to create two files: /etc/nginx/default.d/proxy.conf and /etc/nginx/conf.d/ejbca.conf.&#xA;&#xA;/etc/nginx/default.d/proxy.conf:&#xA;proxysetheader Host              $host;&#xA;proxysetheader X-Real-IP         $remoteaddr;&#xA;proxysetheader X-Forwarded-For   $proxyaddxforwardedfor;&#xA;proxysetheader X-Forwarded-Proto $scheme;&#xA;proxysetheader X-Forwarded-Host  $host;&#xA;proxysetheader Connection        &#34;&#34;;&#xA;&#xA;The following virtual server configuration is somewhat translated from what Keyfactor documentation provides with Apache2, with a slight tweak of using regular HTTP instead of using AJP.&#xA;&#xA;/etc/nginx/conf.d/ejbca.conf:&#xA;server {&#xA;    listen       80;&#xA;    listen       [::]:80;&#xA;    servername  ejbca.example.com;&#xA;    root         /usr/share/nginx/html;&#xA;&#xA;    accesslog /var/log/nginx/ejbcahttpaccess.log combined;&#xA;    errorlog  /var/log/nginx/ejbcahttperror.log  warn;&#xA;&#xA;    include /etc/nginx/default.d/proxy.conf;&#xA;&#xA;    # CRL Distribution Point&#xA;    location = /publicweb/webdist/certdist {&#xA;        if ($argcmd = &#34;crl&#34;) {&#xA;            rewrite ^(.)$ /ejbca$1 break;&#xA;            proxypass http://127.0.0.1:8081;&#xA;            break;&#xA;        }&#xA;        return 301 https://$host$requesturi;&#xA;    }&#xA;&#xA;    # Healthcheck and OCSP&#xA;    location /publicweb/status/ {&#xA;        rewrite ^(.)$ /ejbca$1 break;&#xA;        proxypass http://127.0.0.1:8081;&#xA;    }&#xA;&#xA;    location /ejbca/ {&#xA;        # Only the CRL/OCSP/healthcheck endpoints are allowed in the clear;&#xA;        # any other request redirect to HTTPS.&#xA;        if ($requesturi !~ ^/ejbca/(publicweb/webdist/certdist\?.cmd=crl|publicweb/status/)) {&#xA;            return 301 https://$host$requesturi;&#xA;        }&#xA;        proxypass http://127.0.0.1:8081;&#xA;    }&#xA;&#xA;    location / {&#xA;        return 301 https://$host$requesturi;&#xA;    }&#xA;}&#xA;&#xA;server {&#xA;    listen 443 ssl; # managed by Certbot&#xA;    listen [::]:443 ssl ipv6only=on; # managed by Certbot&#xA;    http2 on;&#xA;    servername  ejbca.example.com;&#xA;&#xA;    root         /usr/share/nginx/html;&#xA;&#xA;    accesslog /var/log/nginx/ejbcahttpsaccess.log combined;&#xA;    errorlog  /var/log/nginx/ejbcahttpserror.log  warn;&#xA;&#xA;    sslcertificate /etc/letsencrypt/live/ejbca.example.com/fullchain.pem; # managed by Certbot&#xA;    sslcertificatekey /etc/letsencrypt/live/ejbca.example.com/privkey.pem; # managed by Certbot&#xA;    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot&#xA;    ssldhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot&#xA;&#xA;    sslclientcertificate    /opt/rootca.pem;&#xA;    sslverifyclient         optional;&#xA;    sslverifydepth          1;&#xA;&#xA;    location /ejbca/adminweb {&#xA;        #if ($sslclientverify != SUCCESS) { return 403; } # uncomment after creating and installing your SuperAdmin certificate then remove the SuperAdmin public access policy.&#xA;        proxypass http://127.0.0.1:8082;&#xA;        include /etc/nginx/default.d/proxy.conf;&#xA;        proxysetheader SSLCLIENTCERT $sslclientcert;&#xA;    }&#xA;    location /adminweb {&#xA;        #if ($sslclientverify != SUCCESS) { return 403; } # uncomment after creating and installing your SuperAdmin certificate then remove the SuperAdmin public access policy.&#xA;        rewrite ^(.)$ /ejbca$1 break;&#xA;        proxypass http://127.0.0.1:8082;&#xA;        include /etc/nginx/default.d/proxy.conf;&#xA;        proxysetheader SSLCLIENTCERT $sslclientcert;&#xA;    }&#xA;&#xA;    location /ejbca/ {&#xA;        proxypass http://127.0.0.1:8082;&#xA;        include /etc/nginx/default.d/proxy.conf;&#xA;        proxysetheader SSLCLIENTCERT $sslclientcert;&#xA;    }&#xA;    location / {&#xA;        rewrite ^(.)$ /ejbca$1 break;&#xA;        proxypass http://127.0.0.1:8082;&#xA;        include /etc/nginx/default.d/proxy.conf;&#xA;        proxysetheader SSLCLIENTCERT $sslclientcert;&#xA;    }&#xA;}&#xA;&#xA;Make sure to have these files readable by NGINX: chmod 644 /etc/nginx/default.d/proxy.conf /etc/nginx/conf.d/ejbca.conf&#xA;&#xA;To make sure everything went okay, reboot the entire server.&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>So normally you&#39;d deploy EJBCA internally. But what if you wanted to publicly use it for SCEP but not want to deploy the ManagementCA to user trust store?</p>

<p>That&#39;s when you&#39;d put EJBCA behind a reverse proxy, but how?</p>



<h2 id="prerequisites" id="prerequisites">Prerequisites</h2>

<p>Prepare your own root CA: You&#39;ll need the keypair as a PKCS#12 file and the root CA certificate itself as a PEM file.</p>

<p>Put the root CA certificate to somewhere the reverse proxy can access. <code>/opt/root_ca.pem</code> would be an example. Make sure it is readable by everyone: <code>chmod 644 /opt/root_ca.pem</code></p>

<h3 id="dns" id="dns">DNS</h3>

<p>Make sure you&#39;ve set up a (sub-)domain that points to your EJBCA server. For this blog post, I&#39;ve chosen <code>ejbca.example.com</code>.</p>

<h2 id="procedure" id="procedure">Procedure</h2>

<p>We&#39;ll go over bootstrapping EJBCA itself and the reverse proxy configuration.</p>

<h3 id="ejbca" id="ejbca">EJBCA</h3>

<p>Bring up EJBCA using Keyfactor&#39;s own Docker Compose file with little modifications:</p>

<pre><code class="language-yaml">---
networks:
  access-bridge:
    driver: bridge
  application-bridge:
    driver: bridge
services:
  ejbca-database:
    container_name: ejbca-database
    image: &#34;library/mariadb:latest&#34;
    restart: unless-stopped
    networks:
      - application-bridge
    environment:
      - MYSQL_ROOT_PASSWORD=foo123
      - MYSQL_DATABASE=ejbca
      - MYSQL_USER=ejbca
      - MYSQL_PASSWORD=ejbca
    volumes:
      - ./datadbdir:/var/lib/mysql:rw
  ejbca:
    hostname: ejbca-node1
    container_name: ejbca
    image: keyfactor/ejbca-ce:latest
    depends_on:
      - ejbca-database
    restart: unless-stopped
    networks:
      - access-bridge
      - application-bridge
    environment:
      - DATABASE_JDBC_URL=jdbc:mariadb://ejbca-database:3306/ejbca?characterEncoding=UTF-8
      - LOG_LEVEL_APP=INFO
      - LOG_LEVEL_SERVER=INFO
      - TLS_SETUP_ENABLED=later
      - PROXY_HTTP_BIND=0.0.0.0
    ports:
      # Proxy port for the HTTP endpoint (normally 8080 when PROXY_HTTP_BIND is not set)
      - &#34;127.0.0.1:8081:8081&#34;
      # Proxy port for the HTTPS endpoint, it is HTTP but has
      # SSL_CLIENT_CERT header support to provide the
      # equivalent of the regular HTTPS endpoint
      # (normally 8443 when PROXY_HTTP_BIND is not set)
      - &#34;127.0.0.1:8082:8082&#34;
</code></pre>

<p>Aside from the addition of <code>restart: unless-stopped</code>, notice that the environment variables <code>TLS_SETUP_ENABLED</code> is set to <code>later</code> and <code>PROXY_HTTP_BIND</code> is set to <code>0.0.0.0</code>. These two makes few changes:</p>
<ul><li>Disable generation of ManagementCA, you need to provide/generate your own CA.</li>
<li>Make Wildfly (the application server) not listen on HTTPS but on two special HTTP proxy ports:
<ul><li><code>8081</code> for regular HTTP traffic, but with proxy header support</li>
<li><code>8082</code> for regular HTTPS traffic, but is HTTP with proxy port and <code>SSL_CLIENT_CERT</code> header support as a way for the reverse proxy to provide the client certificate from an mTLS handshake.</li></ul></li></ul>

<h3 id="reverse-proxy" id="reverse-proxy">Reverse Proxy</h3>

<p>I chose NGINX for this, but you can choose any reverse proxy you want that supports mTLS with a different CA other than the one used for the web service.</p>

<p>Make sure you don&#39;t have any firewall rules blocking the ports <code>80</code> and <code>443</code>.</p>

<p><sub><i>Since I am doing all this in Enterprise Linux, the config file structure is a bit different than the Debian packaging; so be wary.</i></sub></p>

<p>After install, make a copy of <code>/etc/nginx/nginx.conf</code> to a temporary place, you&#39;re going to use it later on: <code>cp -a /etc/nginx/nginx.conf /tmp/nginx_prebootstrap.conf</code></p>

<h4 id="bootstrapping-tls-with-certbot" id="bootstrapping-tls-with-certbot">Bootstrapping TLS with certbot</h4>

<p>Set the <code>server_name</code> variable in the <code>/etc/nginx/nginx.conf</code> file to the (sub-)domain you&#39;ve chosen.</p>

<p>Make sure to have the EPEL repository installed and enabled. Install certbot and its NGINX plugin (<code>dnf install certbot python3-certbot-nginx</code>).</p>

<p>Register your ACME account: <code>certbot register --email your_email@example.com --no-eff-email --agree-tos</code></p>

<p>Obtain your TLS certificate and install it into NGINX automatically: <code>certbot --nginx --domains ejbca.example.com --key-type rsa</code></p>

<h4 id="re-configuring-nginx" id="re-configuring-nginx">Re-configuring NGINX</h4>

<p>Copy back the config file from earlier: <code>cp -af /tmp/nginx_prebootstrap.conf /etc/nginx/nginx.conf</code></p>

<p>Comment out the default server block that&#39;s below the line <code>include /etc/nginx/conf.d/*.conf;</code> in <code>/etc/nginx/nginx.conf</code>. It should look like this:</p>

<p><img src="https://b2.ilter.is/a/4e7d7ee49/b1ba/WinCap_2026-04-21_120559.png" alt="A terminal screenshot showing the nano editor with the NGINX configuration being open."></p>

<p>We&#39;re going to create two files: <code>/etc/nginx/default.d/proxy.conf</code> and <code>/etc/nginx/conf.d/ejbca.conf</code>.</p>

<p><code>/etc/nginx/default.d/proxy.conf</code>:</p>

<pre><code class="language-nginx">proxy_set_header Host              $host;
proxy_set_header X-Real-IP         $remote_addr;
proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host  $host;
proxy_set_header Connection        &#34;&#34;;
</code></pre>

<p>The following virtual server configuration is somewhat translated from what Keyfactor documentation provides with Apache2, with a slight tweak of using regular HTTP instead of using AJP.</p>

<p><code>/etc/nginx/conf.d/ejbca.conf</code>:</p>

<pre><code class="language-nginx">server {
    listen       80;
    listen       [::]:80;
    server_name  ejbca.example.com;
    root         /usr/share/nginx/html;

    access_log /var/log/nginx/ejbca_http_access.log combined;
    error_log  /var/log/nginx/ejbca_http_error.log  warn;

    include /etc/nginx/default.d/proxy.conf;

    # CRL Distribution Point
    location = /publicweb/webdist/certdist {
        if ($arg_cmd = &#34;crl&#34;) {
            rewrite ^(.*)$ /ejbca$1 break;
            proxy_pass http://127.0.0.1:8081;
            break;
        }
        return 301 https://$host$request_uri;
    }

    # Healthcheck and OCSP
    location /publicweb/status/ {
        rewrite ^(.*)$ /ejbca$1 break;
        proxy_pass http://127.0.0.1:8081;
    }

    location /ejbca/ {
        # Only the CRL/OCSP/healthcheck endpoints are allowed in the clear;
        # any other request redirect to HTTPS.
        if ($request_uri !~ ^/ejbca/(publicweb/webdist/certdist\?.*cmd=crl|publicweb/status/)) {
            return 301 https://$host$request_uri;
        }
        proxy_pass http://127.0.0.1:8081;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl; # managed by Certbot
    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    http2 on;
    server_name  ejbca.example.com;

    root         /usr/share/nginx/html;

    access_log /var/log/nginx/ejbca_https_access.log combined;
    error_log  /var/log/nginx/ejbca_https_error.log  warn;

    ssl_certificate /etc/letsencrypt/live/ejbca.example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/ejbca.example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    ssl_client_certificate    /opt/root_ca.pem;
    ssl_verify_client         optional;
    ssl_verify_depth          1;

    location /ejbca/adminweb {
        #if ($ssl_client_verify != SUCCESS) { return 403; } # uncomment after creating and installing your SuperAdmin certificate then remove the SuperAdmin public access policy.
        proxy_pass http://127.0.0.1:8082;
        include /etc/nginx/default.d/proxy.conf;
        proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;
    }
    location /adminweb {
        #if ($ssl_client_verify != SUCCESS) { return 403; } # uncomment after creating and installing your SuperAdmin certificate then remove the SuperAdmin public access policy.
        rewrite ^(.*)$ /ejbca$1 break;
        proxy_pass http://127.0.0.1:8082;
        include /etc/nginx/default.d/proxy.conf;
        proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;
    }


    location /ejbca/ {
        proxy_pass http://127.0.0.1:8082;
        include /etc/nginx/default.d/proxy.conf;
        proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;
    }
    location / {
        rewrite ^(.*)$ /ejbca$1 break;
        proxy_pass http://127.0.0.1:8082;
        include /etc/nginx/default.d/proxy.conf;
        proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;
    }
}
</code></pre>

<p>Make sure to have these files readable by NGINX: <code>chmod 644 /etc/nginx/default.d/proxy.conf /etc/nginx/conf.d/ejbca.conf</code></p>

<p>To make sure everything went okay, reboot the entire server.</p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/ejbca-with-reverse-proxy</guid>
      <pubDate>Tue, 21 Apr 2026 09:44:53 +0000</pubDate>
    </item>
    <item>
      <title>&#34;advanced firewall&#34; rules for RHEL licensing and updates</title>
      <link>https://blog.linuxgemini.space/advanced-firewall-rules-for-rhel-licensing-and-updates</link>
      <description>&lt;![CDATA[had a Fun experience at a customer environment where they have strict network limitations (+ have servers in rather spicy locations)!--more-- so i&#39;ll just cut to the chase:&#xA;&#xA;licensing&#xA;&#xA;for RHEL licensing, there&#39;s two places you have to allow:&#xA;&#xA;Host: subscription.rhn.redhat.com&#xA;  Port: 443&#xA;  Protocol: HTTPS / TLS / TCP&#xA;Host: subscription.rhsm.redhat.com&#xA;  Port: 443&#xA;  Protocol: HTTPS / TLS / TCP&#xA;&#xA;you probably noticed that i haven&#39;t given any IPs yet, there&#39;s a reason for that; i&#39;ll explain at the end.&#xA;&#xA;package updates etc.&#xA;&#xA;Host: cdn.redhat.com&#xA;  Port: 443&#xA;  Protocol: HTTPS / TLS / TCP&#xA;Host: .cdn.redhat.com&#xA;  Port: 443&#xA;  Protocol: HTTPS / TLS / TCP&#xA;&#xA;why the seperate wildcard? well,&#xA;&#xA;what happens when your host is in Russia, Belarus or China?&#xA;&#xA;for Russia and Belarus; first off, your Red Hat account must not be in &#34;Export Hold&#34;; if you are, you&#39;re short of luck from the beginning.&#xA;&#xA;if your Red Hat account is not on &#34;Export Hold&#34; state, your requests to cdn.redhat.com from RU or BY will be magically redirected to ru-by-exceptions.cdn.redhat.com, no configuration change needed.&#xA;&#xA;for China however, the entire RHEL stack goes through one place: china.cdn.redhat.com; this includes licensing as well (so double check your DNF/YUM and subscription-manager configuration, see https://access.redhat.com/solutions/5090421 (login required*)).&#xA;&#xA;hence the wildcard.&#xA;&#xA;why no ip?&#xA;&#xA;other than licensing, everything Red Hat hosts use Akamai&#39;s CDN infrastructure. given that Akamai themselves don&#39;t directly provide IP lists of their CDN nodes, its somewhat hard to limit just per-IP.&#xA;&#xA;for the global cdn.redhat.com endpoint, Red Hat does provide an IP list at https://access.redhat.com/articles/1525183 (no login required). JSON formatted version also available at https://access.redhat.com/sites/default/files/cdnredhatcom_cac.json.&#xA;&#xA;IPs of subdomains designated for Russia, Belarus and China are not provided, thus you always have to resort to SNI based filtering for these.&#xA;&#xA;i mean if you&#39;re using a palo alto firewall and you&#39;re doing IP based filtering, what&#39;s wrong with you&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>had a Fun experience at a customer environment where they have strict network limitations (+ have servers in rather spicy locations) so i&#39;ll just cut to the chase:</p>

<h2 id="licensing" id="licensing">licensing</h2>

<p>for RHEL licensing, there&#39;s two places you have to allow:</p>
<ul><li>Host: <code>subscription.rhn.redhat.com</code>
Port: <code>443</code>
Protocol: <code>HTTPS</code> / <code>TLS</code> / <code>TCP</code></li>
<li>Host: <code>subscription.rhsm.redhat.com</code>
Port: <code>443</code>
Protocol: <code>HTTPS</code> / <code>TLS</code> / <code>TCP</code></li></ul>

<p>you probably noticed that i haven&#39;t given any IPs yet, there&#39;s a reason for that; i&#39;ll explain at the end.</p>

<h2 id="package-updates-etc" id="package-updates-etc">package updates etc.</h2>
<ul><li>Host: <code>cdn.redhat.com</code>
Port: <code>443</code>
Protocol: <code>HTTPS</code> / <code>TLS</code> / <code>TCP</code></li>
<li>Host: <code>*.cdn.redhat.com</code>
Port: <code>443</code>
Protocol: <code>HTTPS</code> / <code>TLS</code> / <code>TCP</code></li></ul>

<p>why the seperate wildcard? well,</p>

<h2 id="what-happens-when-your-host-is-in-russia-belarus-or-china" id="what-happens-when-your-host-is-in-russia-belarus-or-china">what happens when your host is in Russia, Belarus or China?</h2>

<p>for Russia and Belarus; first off, your Red Hat account must not be in “Export Hold”; if you are, you&#39;re short of luck from the beginning.</p>

<p>if your Red Hat account is not on “Export Hold” state, your requests to <code>cdn.redhat.com</code> from RU or BY will be magically redirected to <code>ru-by-exceptions.cdn.redhat.com</code>, no configuration change needed.</p>

<p>for China however, the entire RHEL stack goes through one place: <code>china.cdn.redhat.com</code>; this includes licensing as well (so double check your DNF/YUM <strong><em>and</em></strong> subscription-manager configuration, see <a href="https://access.redhat.com/solutions/5090421">https://access.redhat.com/solutions/5090421</a> (<em>login required</em>)).</p>

<p>hence the wildcard.</p>

<h2 id="why-no-ip" id="why-no-ip">why no ip?</h2>

<p>other than licensing, everything Red Hat hosts use Akamai&#39;s CDN infrastructure. given that Akamai themselves don&#39;t directly provide IP lists of their CDN nodes, its somewhat hard to limit just per-IP.</p>

<p>for the global <code>cdn.redhat.com</code> endpoint, Red Hat does provide an IP list at <a href="https://access.redhat.com/articles/1525183">https://access.redhat.com/articles/1525183</a> (<em><strong>no</strong> login required</em>). JSON formatted version also available at <a href="https://access.redhat.com/sites/default/files/cdn_redhat_com_cac.json">https://access.redhat.com/sites/default/files/cdn_redhat_com_cac.json</a>.</p>

<p>IPs of subdomains designated for Russia, Belarus and China are not provided, thus you always have to resort to SNI based filtering for these.</p>

<p>i mean if you&#39;re using a palo alto firewall and you&#39;re doing IP based filtering, what&#39;s wrong with you</p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/advanced-firewall-rules-for-rhel-licensing-and-updates</guid>
      <pubDate>Thu, 02 Jan 2025 13:59:12 +0000</pubDate>
    </item>
    <item>
      <title>a registry file for new windows installations</title>
      <link>https://blog.linuxgemini.space/a-registry-file-for-new-windows-installations</link>
      <description>&lt;![CDATA[although i rarely (re-)install windows, these settings are quite handy to improve stability in certain situations.!--more--&#xA;&#xA;so here it is, written in .reg file syntax:&#xA;&#xA;Windows Registry Editor Version 5.00&#xA;&#xA;;; Revert the timeBeginPeriod change done in Win10-2004 (flag is only available in Win11+)&#xA;;; https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod#remarks&#xA;;; https://randomascii.wordpress.com/2020/10/04/windows-timer-resolution-the-great-rule-change/ (https://archive.li/OrqYE)&#xA;;;&#xA;;; This fixes audio distortion issues that may come up on Virtual Machines (particularly old Windows versions) in VMware Workstation&#xA;[HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel]&#xA;&#34;GlobalTimerResolutionRequests&#34;=dword:00000001&#xA;&#xA;;; Disable co-installers (auto-installers) that may come with external devices&#xA;[HKEYLOCALMACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer]&#xA;&#34;DisableCoInstallers&#34;=dword:00000001&#xA;&#xA;;; Don&#39;t let Windows Explorer auto-determine the folder type such that it won&#39;t get hung&#xA;[HKEYCURRENTUSER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell]&#xA;&#34;FolderType&#34;=&#34;NotSpecified&#34;&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>although i rarely (re-)install windows, these settings are quite handy to improve stability in certain situations.</p>

<p>so here it is, written in <code>.reg</code> file syntax:</p>

<pre><code>Windows Registry Editor Version 5.00

;; Revert the timeBeginPeriod change done in Win10-2004 (flag is only available in Win11+)
;; https://learn.microsoft.com/en-us/windows/win32/api/timeapi/nf-timeapi-timebeginperiod#remarks
;; https://randomascii.wordpress.com/2020/10/04/windows-timer-resolution-the-great-rule-change/ (https://archive.li/OrqYE)
;;
;; This fixes audio distortion issues that may come up on Virtual Machines (particularly old Windows versions) in VMware Workstation
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\kernel]
&#34;GlobalTimerResolutionRequests&#34;=dword:00000001

;; Disable co-installers (auto-installers) that may come with external devices
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Device Installer]
&#34;DisableCoInstallers&#34;=dword:00000001

;; Don&#39;t let Windows Explorer auto-determine the folder type such that it won&#39;t get hung
[HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\AllFolders\Shell]
&#34;FolderType&#34;=&#34;NotSpecified&#34;
</code></pre>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/a-registry-file-for-new-windows-installations</guid>
      <pubDate>Sat, 14 Dec 2024 03:57:24 +0000</pubDate>
    </item>
    <item>
      <title>desperate measures when you can&#39;t access your ubuntu server</title>
      <link>https://blog.linuxgemini.space/desperate-measures-when-you-cant-access-your-ubuntu-server</link>
      <description>&lt;![CDATA[okay let&#39;s say your server&#39;s networking just dies, you can access its serial and visual console...&#xA;&#xA;...but you don&#39;t know root/user password(s). what would you do?!--more--&#xA;&#xA;well, this is something a friend encountered with their two oracle cloud servers.&#xA;&#xA;as a prerequisite, you need to reset the root password. unless you run a hardened system image, this should be doable with changing the boot command line to initialize bash, rather than whatever initsystem the image uses. this has been documented many times.&#xA;&#xA;resetting the root password&#xA;&#xA;to do this; first you need to generate the remote console keys for the virtual instance from the oracle cloud console.&#xA;&#xA;then, connect to the vnc console using the long command oracle gives you. (for windows, you need to install the putty suite tools because plink is required; oh and a vnc client.)&#xA;&#xA;the command should open port 5900 for your vnc client to connect to the console proper.&#xA;&#xA;send a ctrl-alt-del signal or issue a reset from the cloud console.&#xA;&#xA;hit esc right after texts above the tianocore logo shows up. hope that the grub menu appears. if it does, you can follow the many tutorials i linked above. if it doesn&#39;t, well, you&#39;re fucked.&#xA;&#xA;the hail mary approach&#xA;&#xA;...not that fucked, though.&#xA;&#xA;if you hit esc early, you might&#39;ve entered the uefi menu instead. for which instead of resetting you enter the boot menu to enter the efi shell. hit any key other than esc to drop into the shell itself.&#xA;&#xA;initial screenshot of the efi shell&#xA;&#xA;run type fs0:\EFI\ubuntu\grub.cfg and note the value at the end of the line starting with search.&#xA;&#xA;a printout of the grub configuration for the efi partition&#xA;&#xA;the efi shell should give a crude editor to mess with the grub config, so run edit fs0:\EFI\ubuntu\grub.cfg and add a space withinin the value of the configfile line. yes you&#39;re intentionally breaking grub here. by breaking the configline instruction; you&#39;re making grub partially set up to use the correct /boot (or /) partition.&#xA;&#xA;reboot again, you should drop to a regular grub shell this time.&#xA;&#xA;you can use source (thepartition,younoted)/boot/grub/grub.cfg to load the system environment but not execute it.&#xA;&#xA;initial grub shell&#xA;&#xA;run cat (thepartition,younoted)/boot/grub/grub.cfg and note the boot and initrd lines, if you can see them.&#xA;&#xA;boot parameters from the actual grub configuration&#xA;&#xA;you can then write those two lines by hand, but changing the ro to rw init=/bin/bash in the linux line like in the tutorials and removing the rest after that ro.&#xA;&#xA;then run normal. you should be in bash in a moment. do the passwd trick (like in the tutorials) and then issue a ctrl-alt-del or a reset from the cloud console.&#xA;&#xA;since you broke the config in the efi partition (esp) you will be dropped back into the grub shell, this time run configfile (thepartition,younoted)/boot/grub/grub.cfg so that the system boots.&#xA;&#xA;then just login with your new password, make sure that you run update-grub to fix the issues you created previously :p&#xA;&#xA;double check if its fixed by checking /boot/efi/EFI/ubuntu/grub.cfg.&#xA;&#xA;exporting files when you don&#39;t have working virtual cloud network&#xA;&#xA;i don&#39;t know how can this happen @ oracle cloud but i&#39;ve had first-hand experience, so yeah.&#xA;&#xA;we wanted to export at least a home directory so we did something very cursed.&#xA;&#xA;tarball the folder, reconnect to the console using the text-serial endpoint instead of vnc while piping the output to a file, and run base64. &#xA;&#xA;it did take like 1-2 hours for 2 tarballs but it worked /shrug&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>okay let&#39;s say your server&#39;s networking just <em>dies</em>, you can access its serial and visual console...</p>

<p>...but you don&#39;t know root/user password(s). what would you do?</p>

<p>well, this is something a friend encountered with their two oracle cloud servers.</p>

<p>as a prerequisite, you need to reset the root password. unless you run a hardened system image, this should be doable with changing the boot command line to initialize bash, rather than whatever initsystem the image uses. <a href="https://vitux.com/ubuntu-reset-root-password/">this</a> <a href="https://linuxconfig.org/ubuntu-20-04-reset-root-password">has</a> <a href="https://www.tecmint.com/reset-forgotten-root-password-in-ubuntu/">been</a> <a href="https://linuxiac.com/how-to-reset-root-password-in-linux/">documented</a> <a href="https://www.howtogeek.com/1287/reset-your-forgotten-ubuntu-password-in-2-minutes-or-less/#:~:text=Alternate%20Root%20Shell%20Method">many</a> <a href="https://www.how2shout.com/linux/how-to-reset-ubuntu-22-04-lts-root-password/">times</a>.</p>

<h2 id="resetting-the-root-password" id="resetting-the-root-password">resetting the root password</h2>

<p>to do this; first you need to generate the remote console keys for the virtual instance from the oracle cloud console.</p>

<p>then, connect to the vnc console using the long command oracle gives you. (for windows, you need to install the putty suite tools because plink is required; oh and a vnc client.)</p>

<p>the command should open port 5900 for your vnc client to connect to the console proper.</p>

<p>send a ctrl-alt-del signal or issue a reset from the cloud console.</p>

<p>hit esc right after texts above the tianocore logo shows up. <em>hope</em> that the grub menu appears. if it does, you can follow the many tutorials i linked above. if it doesn&#39;t, well, you&#39;re fucked.</p>

<h3 id="the-hail-mary-approach" id="the-hail-mary-approach">the hail mary approach</h3>

<p>...not <em>that</em> fucked, though.</p>

<p>if you hit esc early, you might&#39;ve entered the uefi menu instead. for which <em>instead of resetting</em> you enter the boot menu to enter the efi shell. hit any key other than esc to drop into the shell itself.</p>

<p><img src="https://b2.ilter.is/a/23e4fbbf0/4ad0/WinCap_2024-04-07_231141.png" alt="initial screenshot of the efi shell"></p>

<p>run <code>type fs0:\EFI\ubuntu\grub.cfg</code> and note the value at the end of the line starting with <code>search</code>.</p>

<p><img src="https://b2.ilter.is/a/ab6cf965a/fc72/WinCap_2024-04-07_231437.png" alt="a printout of the grub configuration for the efi partition"></p>

<p>the efi shell should give a crude editor to mess with the grub config, so run <code>edit fs0:\EFI\ubuntu\grub.cfg</code> and <em>add a space withinin the value of the <code>configfile</code> line.</em> yes you&#39;re intentionally breaking grub here. by breaking the <code>configline</code> instruction; you&#39;re making grub partially set up to use the correct <code>/boot</code> (or <code>/</code>) partition.</p>

<p>reboot again, you should drop to a regular grub shell this time.</p>

<p>you can use <code>source (the_partition,you_noted)/boot/grub/grub.cfg</code> to load the system environment but not execute it.</p>

<p><img src="https://b2.ilter.is/a/d0af2c19f/3620/WinCap_2024-04-07_232733.png" alt="initial grub shell"></p>

<p>run <code>cat (the_partition,you_noted)/boot/grub/grub.cfg</code> and note the boot and initrd lines, <em>if you can see them</em>.</p>

<p><img src="https://b2.ilter.is/a/fb8616df1/d4d6/WinCap_2024-04-07_232539.png" alt="boot parameters from the actual grub configuration"></p>

<p>you can then write those two lines by hand, but changing the <code>ro</code> to <code>rw init=/bin/bash</code> in the <code>linux</code> line like in the tutorials and removing the rest after that <code>ro</code>.</p>

<p>then run <code>normal</code>. you should be in bash in a moment. do the passwd trick (like in the tutorials) and then issue a ctrl-alt-del or a reset from the cloud console.</p>

<p>since you broke the config in the efi partition (esp) you will be dropped back into the grub shell, this time run <code>configfile (the_partition,you_noted)/boot/grub/grub.cfg</code> so that the system boots.</p>

<p>then just login with your new password, make sure that you run <code>update-grub</code> to fix the issues you created previously :p</p>

<p>double check if its fixed by checking <code>/boot/efi/EFI/ubuntu/grub.cfg</code>.</p>

<h2 id="exporting-files-when-you-don-t-have-working-virtual-cloud-network" id="exporting-files-when-you-don-t-have-working-virtual-cloud-network">exporting files when you don&#39;t have working virtual cloud network</h2>

<p>i don&#39;t know how can this happen @ oracle cloud but i&#39;ve had first-hand experience, so yeah.</p>

<p>we wanted to export at least a home directory so we did something very cursed.</p>

<p>tarball the folder, reconnect to the console using the text-serial endpoint instead of vnc while piping the output to a file, and run <code>base64</code>.</p>

<p>it did take like 1-2 hours for 2 tarballs but it worked /shrug</p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/desperate-measures-when-you-cant-access-your-ubuntu-server</guid>
      <pubDate>Sun, 07 Apr 2024 19:52:03 +0000</pubDate>
    </item>
    <item>
      <title>a tiny rant about SSL certificate deployment in web servers</title>
      <link>https://blog.linuxgemini.space/a-tiny-rant-about-ssl-certificate-deployment-in-web-servers</link>
      <description>&lt;![CDATA[did you know that you have to provide a full certificate trust chain for getting almost every web (or any SSL) client to use your website (or service) with TLS?&#xA;&#xA;...but you can still visit some websites with your browser that don&#39;t do this?!--more--&#xA;&#xA;you probably didn&#39;t realize this unless you ran cURL on a website and got a nice little error like this:&#xA;&#xA;(sorry for the people at TUBİTAK ULAKBİM; i had to use a current example)&#xA;&#xA;~ ❯ curl -v https://ulakbim.tubitak.gov.tr&#xA;Trying 193.140.74.21:443...&#xA;Connected to ulakbim.tubitak.gov.tr (193.140.74.21) port 443&#xA;ALPN: curl offers h2,http/1.1&#xA;TLSv1.3 (OUT), TLS handshake, Client hello (1):&#xA;CAfile: /opt/local/share/curl/curl-ca-bundle.crt&#xA;CApath: none&#xA;TLSv1.3 (IN), TLS handshake, Server hello (2):&#xA;TLSv1.2 (IN), TLS handshake, Certificate (11):&#xA;TLSv1.2 (OUT), TLS alert, unknown CA (560):&#xA;SSL certificate problem: unable to get local issuer certificate&#xA;Closing connection&#xA;curl: (60) SSL certificate problem: unable to get local issuer certificate&#xA;More details here: https://curl.se/docs/sslcerts.html&#xA;&#xA;curl failed to verify the legitimacy of the server and therefore could not&#xA;establish a secure connection to it. To learn more about this situation and&#xA;how to fix it, please visit the web page mentioned above.&#xA;~ ❯&#xA;&#xA;but if i use msedge, the site loads just fine with TLS:&#xA;&#xA;Screenshot of ULAKBİM&#39;s website, visited with Microsoft Edge.&#xA;&#xA;you might (understandably) think &#34;did the root CA update and not in the trusted keystore?&#34;, but the reality is a little bit different. the latter thought is true, but not in the way you&#39;d expect.&#xA;&#xA;most TLS certificates in the public web would have a chain like this (some exceptions apply, i won&#39;t talk about them here):&#xA;&#xA;Chain of Trust&#xA;&#xA;essentially, a cert will point to its issuer until it hits a self-signed one.&#xA;&#xA;many systems will include only the root CAs approved by CA/Browser Forum sup(post-publication edit, thanks @mmerkel):/sup the root store operator (usually the vendor) of the system.&#xA;&#xA;this means that the information about intermediates don&#39;t exist unless the server gives information about it (the public keys of both the intermediate and root).&#xA;&#xA;when you misconfigure your webserver to use only the host certificate for the public key/certificate, the public key/certificate of the intermediate (and root) will be missing. the only thing available will be the issuer certificate serial and its metadata.&#xA;&#xA;browsers and some OSes like Android include trusted intermediates in their trusted keystore as well. this eliminates the requirement for the server to provide a full trust chain. this obviously create a false sensation of &#34;yeah this works fine&#34;.&#xA;&#xA;but when you check the server with a TLS client like OpenSSL&#39;s sclient, the issue comes clear:&#xA;&#xA;(again, sorry for the people at TUBİTAK ULAKBİM)&#xA;&#xA;~ ❯ openssl sclient -connect ulakbim.tubitak.gov.tr:443 -servername ulakbim.tubitak.gov.tr&#xA;CONNECTED(00000005)&#xA;depth=0 C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = .tubitak.gov.tr&#xA;verify error:num=20:unable to get local issuer certificate&#xA;verify return:1&#xA;depth=0 C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = .tubitak.gov.tr&#xA;verify error:num=21:unable to verify the first certificate&#xA;verify return:1&#xA;depth=0 C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = .tubitak.gov.tr&#xA;verify return:1&#xA;---&#xA;Certificate chain&#xA; 0 s:C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = .tubitak.gov.tr&#xA;   i:C = TR, L = Gebze - Kocaeli, O = Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK, OU = Kamu Sertifikasyon Merkezi - Kamu SM, CN = TUBITAK Kamu SM SSL Sertifika Hizmet Saglayicisi - Surum 1&#xA;   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256&#xA;   v:NotBefore: Jul 20 13:34:02 2023 GMT; NotAfter: Jul 20 13:34:02 2024 GMT&#xA;---&#xA;Server certificate&#xA;-----BEGIN CERTIFICATE-----&#xA;[output snipped]&#xA;&#xA;now let&#39;s look at a properly configured server:&#xA;&#xA;~ ❯ openssl s_client -connect blog.linuxgemini.space:443 -servername blog.linuxgemini.space&#xA;CONNECTED(00000005)&#xA;depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1&#xA;verify return:1&#xA;depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1P5&#xA;verify return:1&#xA;depth=0 CN = linuxgemini.space&#xA;verify return:1&#xA;---&#xA;Certificate chain&#xA; 0 s:CN = linuxgemini.space&#xA;   i:C = US, O = Google Trust Services LLC, CN = GTS CA 1P5&#xA;   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256&#xA;   v:NotBefore: Nov 21 06:59:19 2023 GMT; NotAfter: Feb 19 06:59:18 2024 GMT&#xA; 1 s:C = US, O = Google Trust Services LLC, CN = GTS CA 1P5&#xA;   i:C = US, O = Google Trust Services LLC, CN = GTS Root R1&#xA;   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256&#xA;   v:NotBefore: Aug 13 00:00:42 2020 GMT; NotAfter: Sep 30 00:00:42 2027 GMT&#xA; 2 s:C = US, O = Google Trust Services LLC, CN = GTS Root R1&#xA;   i:C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA&#xA;   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256&#xA;   v:NotBefore: Jun 19 00:00:42 2020 GMT; NotAfter: Jan 28 00:00:42 2028 GMT&#xA;---&#xA;Server certificate&#xA;-----BEGIN CERTIFICATE-----&#xA;[output snipped]&#xA;&#xA;you can clearly see that a trust chain is delivered by the server to the client, which the client successfully verifies with its trusted keystore, because GTS Root R1 exists in the keystore. the chain from linuxgemini.space to GTS CA 1P5 to GTS Root R1 is properly documented and delivered by the server.&#xA;&#xA;(now you might ask why GlobalSign Root CA isn&#39;t sent, that&#39;s because both GlobalSign and Google Trust Services certificates are in the keystore, which makes that part of the chain redundant.)&#xA;&#xA;so in the end; what i want to say is &#34;please use fullchain.pem when you are deploying a server with TLS, you can make one if you don&#39;t have any. its just appending each pem file (cert, intermediate cert, root ca cert).&#34;&#xA;&#xA;---&#xA;&#xA;i had the idea to write this post when i was editing pages on bgp.tools.&#xA;&#xA;Screenshot of a Discord conversation between me and Ben Cartwright-Cox, about this topic while doing stuff with bgp.tools.&#xA;&#xA;sorry again for the infodump, ben.&#xA;&#xA;2024-08-08 edit: last year at CCC (37C3) ben made a great lightning talk about this topic, you can watch it at https://media.ccc.de/v/37c3-lightningtalks-58049-browsers-biggest-tls-mistake&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>did you know that you have to provide a full certificate trust chain for getting almost every web (or any SSL) client to use your website (or service) with TLS?</p>

<p>...but you can still visit some websites <strong><em>with your browser</em></strong> that don&#39;t do this?</p>

<p>you <em>probably</em> didn&#39;t realize this <strong><em>unless you ran cURL</em></strong> on a website and got a nice little error like this:</p>

<p>(sorry for the people at TUBİTAK ULAKBİM; i had to use a current example)</p>

<pre><code>~ ❯ curl -v https://ulakbim.tubitak.gov.tr
*   Trying 193.140.74.21:443...
* Connected to ulakbim.tubitak.gov.tr (193.140.74.21) port 443
* ALPN: curl offers h2,http/1.1
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
*  CAfile: /opt/local/share/curl/curl-ca-bundle.crt
*  CApath: none
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: unable to get local issuer certificate
* Closing connection
curl: (60) SSL certificate problem: unable to get local issuer certificate
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
~ ❯
</code></pre>

<p>but if i use msedge, the site loads just fine with TLS:</p>

<p><img src="https://b2.ilter.is/a/b2f3324ee/Screenshot+2023-12-07+at+19.15.48.png" alt="Screenshot of ULAKBİM&#39;s website, visited with Microsoft Edge."></p>

<p>you might (understandably) think “did the root CA update and not in the trusted keystore?”, but the reality is a little bit different. the latter thought <em>is true</em>, but not in the way you&#39;d expect.</p>

<p>most TLS certificates in the public web would have a chain like this (some exceptions apply, i won&#39;t talk about them here):</p>

<p><img src="https://b2.ilter.is/a/6de00fc91/49d0/chain_of_trust.svg" alt="Chain of Trust"></p>

<p>essentially, a cert will point to its issuer until it hits a self-signed one.</p>

<p><em>many</em> systems will include <strong>only</strong> the <em>root CAs</em> approved by <del>CA/Browser Forum</del> <sup>(post-publication edit, thanks @mmerkel):</sup> the root store operator (usually the vendor) of the system.</p>

<p>this means that the information about intermediates don&#39;t exist <em>unless the server gives information about it</em> (the public keys of both the intermediate and root).</p>

<p>when you misconfigure your webserver to use only the host certificate for the public key/certificate, the public key/certificate of the intermediate (and root) will be missing. the only thing available will be the issuer certificate serial and its metadata.</p>

<p>browsers and <em>some</em> OSes like Android include trusted intermediates in their trusted keystore as well. this eliminates the requirement for the server to provide a full trust chain. <strong><em>this obviously create a false sensation of “yeah this works fine”.</em></strong></p>

<p>but when you check the server with a TLS client like OpenSSL&#39;s <code>s_client</code>, the issue comes clear:</p>

<p>(again, sorry for the people at TUBİTAK ULAKBİM)</p>

<pre><code>~ ❯ openssl s_client -connect ulakbim.tubitak.gov.tr:443 -servername ulakbim.tubitak.gov.tr
CONNECTED(00000005)
depth=0 C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = *.tubitak.gov.tr
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = *.tubitak.gov.tr
verify error:num=21:unable to verify the first certificate
verify return:1
depth=0 C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = *.tubitak.gov.tr
verify return:1
---
Certificate chain
 0 s:C = TR, ST = KOCAELI, O = TUBITAK BILGEM, CN = *.tubitak.gov.tr
   i:C = TR, L = Gebze - Kocaeli, O = Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK, OU = Kamu Sertifikasyon Merkezi - Kamu SM, CN = TUBITAK Kamu SM SSL Sertifika Hizmet Saglayicisi - Surum 1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jul 20 13:34:02 2023 GMT; NotAfter: Jul 20 13:34:02 2024 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
[output snipped]
</code></pre>

<p>now let&#39;s look at a properly configured server:</p>

<pre><code>~ ❯ openssl s_client -connect blog.linuxgemini.space:443 -servername blog.linuxgemini.space
CONNECTED(00000005)
depth=2 C = US, O = Google Trust Services LLC, CN = GTS Root R1
verify return:1
depth=1 C = US, O = Google Trust Services LLC, CN = GTS CA 1P5
verify return:1
depth=0 CN = linuxgemini.space
verify return:1
---
Certificate chain
 0 s:CN = linuxgemini.space
   i:C = US, O = Google Trust Services LLC, CN = GTS CA 1P5
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Nov 21 06:59:19 2023 GMT; NotAfter: Feb 19 06:59:18 2024 GMT
 1 s:C = US, O = Google Trust Services LLC, CN = GTS CA 1P5
   i:C = US, O = Google Trust Services LLC, CN = GTS Root R1
   a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
   v:NotBefore: Aug 13 00:00:42 2020 GMT; NotAfter: Sep 30 00:00:42 2027 GMT
 2 s:C = US, O = Google Trust Services LLC, CN = GTS Root R1
   i:C = BE, O = GlobalSign nv-sa, OU = Root CA, CN = GlobalSign Root CA
   a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA256
   v:NotBefore: Jun 19 00:00:42 2020 GMT; NotAfter: Jan 28 00:00:42 2028 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
[output snipped]
</code></pre>

<p>you can clearly see that a trust chain is delivered by the server to the client, which the client successfully verifies with its trusted keystore, because <code>GTS Root R1</code> exists in the keystore. the chain from <code>linuxgemini.space</code> to <code>GTS CA 1P5</code> to <code>GTS Root R1</code> is properly documented and delivered by the server.</p>

<p>(now you might ask why <code>GlobalSign Root CA</code> isn&#39;t sent, that&#39;s because both GlobalSign and Google Trust Services certificates are in the keystore, which makes that part of the chain redundant.)</p>

<p>so in the end; what i want to say is <strong>“please use <code>fullchain.pem</code> when you are deploying a server with TLS, you can make one if you don&#39;t have any. its just appending each pem file (cert, intermediate cert, root ca cert).”</strong></p>

<hr>

<p>i had the idea to write this post when i was editing pages on <a href="https://bgp.tools">bgp.tools</a>.</p>

<p><img src="https://b2.ilter.is/a/40cdc9179/Screenshot+2023-12-07+at+20.07.02.png" alt="Screenshot of a Discord conversation between me and Ben Cartwright-Cox, about this topic while doing stuff with bgp.tools."></p>

<p>sorry again for the infodump, ben.</p>

<p><strong><em>2024-08-08 edit:</em></strong> last year at CCC (37C3) ben made a great lightning talk about this topic, you can watch it at <a href="https://media.ccc.de/v/37c3-lightningtalks-58049-browsers-biggest-tls-mistake">https://media.ccc.de/v/37c3-lightningtalks-58049-browsers-biggest-tls-mistake</a></p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/a-tiny-rant-about-ssl-certificate-deployment-in-web-servers</guid>
      <pubDate>Thu, 07 Dec 2023 16:21:46 +0000</pubDate>
    </item>
    <item>
      <title>Gümrük vergisini göndericinin ödediği paketin normal usul gümrüğe girmesi eğlencesi</title>
      <link>https://blog.linuxgemini.space/mclarenmerch-dhl-gumruk</link>
      <description>&lt;![CDATA[Efendim hikaye ufaktan (traji)komik; olay McLaren F1 takımının Suzuka&#39;da 2 podyum kapmasıyla başlıyor.!--more--&#xA;&#xA;Tabi takım o kadar mutlu olacak ki merch mağazalarında kullanabileceğiniz 2 gün geçerli bir indirim kodu duyuruyorlar:&#xA;&#xA;blockquote class=&#34;twitter-tweet&#34;p lang=&#34;en&#34; dir=&#34;ltr&#34;This one&amp;#39;s for you, McLaren fans! 🏆 brbrThank you for your support. Thank you for sticking with us. 🧡 Enjoy 60% off at the McLaren Store using the code: PODIUM60 👇/p&amp;mdash; McLaren (@McLarenF1) a href=&#34;https://twitter.com/McLarenF1/status/1705850283534733513?refsrc=twsrc%5Etfw&#34;September 24, 2023/a/blockquote script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;/script&#xA;&#xA;E haliyle biz de abanıyoruz biraz:&#xA;&#xA;McLaren Store&#39;dan sipariş verdiğime dair ekran görüntüsü.&#xA;&#xA;Ekranda &#34;Duties&#34;e 0 Lira yazıp 322.98 Vergi yazınca kafama takıldı, &#34;gümrük vergisini ben mi ödeyeceğim&#34; diye.&#xA;&#xA;Hemen gönderim bilgi sayfasına bir daha bakıyorum, daha önce de okuduğum paragrafı bir daha okuyorum kendime:&#xA;&#xA;  Please ensure that when placing an order that the country of shipping destination is selected correctly. This is to ensure no extra charges are applied at customs.&#xA;&#xA;İçim biraz rahatlıyor en azından vergiyi McLaren ödeyecek diye. Kafamda da toplam ödediğim para o günün kuruyla yaklaşık 97 Avro&#39;ya geliyor diye de seviniyordum.&#xA;&#xA;---&#xA;&#xA;Gel gelelim bu paket 18 Ekim&#39;de ülkeye gelsin, bir güzel de gümrüğe düşsün, SMS&#39;i de gelsin.&#xA;&#xA;DHL&#39;i aradıktan sonra öğreniyorum ki bildirilen toplam değer 208 Pound (GBP) olduğundan (haliyle 150 Avro&#39;yu aşıyor) standart gümrüğe tabi tutulacak. Diyorum &#34;ya ben buna bu kadar para vermedim nasıl giriyor&#34;, DHL de &#34;ilk muayenede böyle çıktı, bizim yapabileceğimiz pek bir şey yok&#34; diyorlar.&#xA;&#xA;Tabi haliyle DHL bana seçeneklerimi sunuyor:&#xA;  Paket DTPsup id=&#34;a1&#34;1/sup olduğundan gümrük kanunu uyarınca ülkeye geldikten sonraki ilk 20 gün içinde fiziken verilmesi gereken belgeleri DHL Global Forwarding&#39;e postalayarak çekim işlemlerini başlatmak ve beklemek.&#xA;  Ülkeye geldikten sonraki ilk 14 gün içinde McLaren ile görüşüp paketin iade sürecini başlatmak.&#xA;  Hiçbir şey yapmayıp paketin tasfiye edilmesine müsaade etmek.&#xA;&#xA;İlk seçeneği seçiyorum, bakalım ne olacak diye. Tabi UPS ile yaşadığım kıyameti yaşamamayı umutluyorum burda.&#xA;&#xA;---&#xA;&#xA;24 Ekim&#39;de DGF Gümrük Müşavirliği (DHL Global Forwarding&#39;dir kendileri) bana e-posta atıyor, şu form ve belgeleri e-posta ile, paket TAREKS&#39;e tabi olduğundan şu belgelerin aslını_ posta ile göndermeniz gerekiyor diye (bu sayfa sonunda yazıyor hepsi). Fakat bazı belgelerin örnekleri yok, misal TAREKS beyannamesi için gereken şablon ve dilekçe.&#xA;&#xA;25 Ekim&#39;de, ilgilenen arkadaşın telefonunu arayınca olay anlaşılıyor: bana gelen e-postanın ekleri eksikmiş.&#xA;&#xA;Ekleri yolladıktan hemen sonra, gereken belgeleri çıkarıp, doldurup, imzalayıp, tarayıp, derleyip toparladıktan sonra noter yolunu tuttum.&#xA;&#xA;Noterde 10 dakika (ve 569 Lira) sonrasında noter yakındaki PTT&#39;ye gidip 62 Lira ödedikten sonra belgeleri postaladım. PTT, İstanbul&#39;da bir tuhaf çalışıyor. 6 gün (4 iş günü) sürdü belgelerin varması. Tersi olsa, Ankara&#39;ya net 1 günde sorunsuz getiriyorlar.&#xA;&#xA;2 Kasım&#39;da DGF&#39;den başka bir arkadaş işlemlere başlandığını, olası gelişmelerden haberdar edeceğini iletiyor. Tabi TAREKS için 500 Lira da buradan gitti (sanırım duruma göre bu paranın iadesini isteyebiliyorum, emin değilim).&#xA;&#xA;5 gün (3 iş günü) sessizlikten sonra, 7 Kasım akşamında, soruyorum bir gelişme oldu mu diye. 8&#39;inin sabahında hemen cevap geliyor: &#34;dün beyanatta bulunduk, öğleye kadar dosya kapanır, öğleden sonra çıkış veririz&#34; diye. Hakikaten de paket öğleden sonra gümrükten çıktı.&#xA;&#xA;Aha bugün 9 Kasım, paket geldi. Paketin bi tarafının etrafı &#34;İncelendi&#34; bantıyla sarılı tabi. Neyse ürünler sağlam ama. Kargo irsaliyesinde DDP, kargo etiketinde DTP yazması da ekstra ironik ;)&#xA;&#xA;---&#xA;&#xA;Buraya kadar hep kibar davranan DHL (ve DGF) görevlilerine teşekkür etmek istiyorum. E-posta ekinin eksik gelmesi sorunu dışında her şey akıcı gerçekleşti. Bu kadar frictionless bir deneyim beklemiyordum şahsen.&#xA;&#xA;DHL Gümrük Portal&#39;ına bakmadıysanız bi bakın derim: https://gumruk.dhl.com.tr&#xA;&#xA;Kendi gümrük rehberleri de şurada mevcut: https://gumruk.dhl.com.tr/Content/documents/Gumruk%20Musteri%20Rehberi.pdf&#xA;&#xA;---&#xA;&#xA;DGF benden şu belgeleri E-posta ile göndermemi istedi:&#xA;&#xA;  - Dolaylı Temsil Yetki Belgesi (insNoterden Tasdik Ettirilmez/ins) - (Fatura üzerindeki alıcı tarafından doldurulmalı ve imzalanmalıdır),&#xA;  - İthalat Gümrükleme Talimatı (Fatura üzerindeki alıcı tarafından doldurulmalı ve imzalanmalıdır),&#xA;  - Yurdışına yapılan ödemenin K.kartı ekstre görünütüsü veya ödemenin banka uygulaması üzerindeki ekran görünütüsü,&#xA;  - Order Details – Order İnformation görselleri&#xA;  - Kimlik Fotokopisi,&#xA;&#xA;Dolaylı Temsil Yetki Belgesi ve İthalat Gümrükleme Talimatı ekte olması gerekiyor.&#xA;&#xA;DGF benden şu belgeleri paket TAREKS&#39;e tabii olduğundan dolayı Posta ile ofislerine ulaştırmamı istedi:&#xA;&#xA;  - Gerçek Kişi Adına Kayıt Dilekçesi – İsim Soyisim imzalı&#xA;  - Tareks Taahütnamesi – Noter Tasdikli ( Geçerlilik tarihi minimum 1 sene olmak üzere dilediğiniz tarihe kadar belirlenebilir. [isim gizlendi] ismi ve bilgileri sabit kalmalıdır)&#xA;  - İmza Beyannemesi – Noter Tasdikli (noterden talep edilmelidir)&#xA;  - Vergi Mükellefiyet yazısı – E Devlet https://dijital.gib.gov.tr/portal/mukellefiyet-borc-durum-yazilarim Dilekçelerim  Mükellefiyet/Borç Durum Yazılarım  YENİ TALEP OLUŞTUR  Mükellefiyet Yazısı Talebi  Merkez Adımlarını takip ederek belge oluşturulacaktır&#xA; &#xA;---&#xA;&#xA;b id=&#34;f1&#34;1/b: Burada ufak bi durum var, Incoterms® 2020 ile ortalık karışmış durumda. DHL, (anladığım kadarıyla) Türkiye&#39;de bireysel alıcılar ve/veya göndericiler için &#34;basitleştirilmiş&#34; DTP (Duty Taxes Paid) ve DTU (Duty Taxes Unpaid) terimlerini kullanıyor. DHL, Hollanda&#39;da da bu formatı kullanıyor. UPS, Türkiye&#39;de DDP (Delivery Duty Paid) ve DDU (Delivery Duty Unpaid) kullanıyor diye hatırlıyorum.↩&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>Efendim hikaye ufaktan (traji)komik; olay McLaren F1 takımının Suzuka&#39;da 2 podyum kapmasıyla başlıyor.</p>

<p>Tabi takım o kadar mutlu olacak ki merch mağazalarında kullanabileceğiniz 2 gün geçerli bir indirim kodu duyuruyorlar:</p>

<p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">This one&#39;s for you, McLaren fans! 🏆 <br><br>Thank you for your support. Thank you for sticking with us. 🧡 Enjoy 60% off at the McLaren Store using the code: PODIUM60 👇</p>— McLaren (@McLarenF1) <a href="https://twitter.com/McLarenF1/status/1705850283534733513?ref_src=twsrc%5Etfw">September 24, 2023</a></blockquote> </p>

<p>E haliyle biz de abanıyoruz biraz:</p>

<p><img src="https://b2.ilter.is/a/749b839fe/7e17/WinCap_2023-11-09_112959.png" alt="McLaren Store&#39;dan sipariş verdiğime dair ekran görüntüsü."></p>

<p>Ekranda “Duties”e 0 Lira yazıp 322.98 Vergi yazınca kafama takıldı, “gümrük vergisini ben mi ödeyeceğim” diye.</p>

<p>Hemen <a href="https://www.mclarenstore.com/delivery">gönderim bilgi sayfasına</a> bir daha bakıyorum, daha önce de okuduğum paragrafı bir daha okuyorum kendime:</p>

<blockquote><p>Please ensure that when placing an order that the country of shipping destination is selected correctly. This is to ensure no extra charges are applied at customs.</p></blockquote>

<p>İçim biraz rahatlıyor en azından vergiyi McLaren ödeyecek diye. Kafamda da toplam ödediğim para o günün kuruyla yaklaşık 97 Avro&#39;ya geliyor diye de seviniyordum.</p>

<hr>

<p>Gel gelelim bu paket 18 Ekim&#39;de ülkeye gelsin, bir güzel de gümrüğe düşsün, SMS&#39;i de gelsin.</p>

<p>DHL&#39;i aradıktan sonra öğreniyorum ki bildirilen toplam değer 208 Pound (GBP) olduğundan (haliyle 150 Avro&#39;yu aşıyor) standart gümrüğe tabi tutulacak. Diyorum “ya ben buna bu kadar para vermedim nasıl giriyor”, DHL de “ilk muayenede böyle çıktı, bizim yapabileceğimiz pek bir şey yok” diyorlar.</p>

<p>Tabi haliyle DHL bana seçeneklerimi sunuyor:
  1. Paket DTP<a href="#f1"><sup id="a1" id="a1">1</sup></a> olduğundan gümrük kanunu uyarınca ülkeye geldikten sonraki ilk 20 gün içinde fiziken verilmesi gereken belgeleri DHL Global Forwarding&#39;e postalayarak çekim işlemlerini başlatmak ve beklemek.
  2. Ülkeye geldikten sonraki ilk 14 gün içinde McLaren ile görüşüp paketin iade sürecini başlatmak.
  3. Hiçbir şey yapmayıp paketin tasfiye edilmesine müsaade etmek.</p>

<p>İlk seçeneği seçiyorum, bakalım ne olacak diye. Tabi UPS ile yaşadığım kıyameti yaşamamayı umutluyorum burda.</p>

<hr>

<p>24 Ekim&#39;de DGF Gümrük Müşavirliği (DHL Global Forwarding&#39;dir kendileri) bana e-posta atıyor, şu form ve belgeleri e-posta ile, paket TAREKS&#39;e tabi olduğundan şu belgelerin <em>aslını</em> posta ile göndermeniz gerekiyor diye (bu sayfa sonunda yazıyor hepsi). Fakat bazı belgelerin örnekleri yok, misal TAREKS beyannamesi için gereken şablon ve dilekçe.</p>

<p>25 Ekim&#39;de, ilgilenen arkadaşın telefonunu arayınca olay anlaşılıyor: bana gelen e-postanın ekleri eksikmiş.</p>

<p>Ekleri yolladıktan hemen sonra, gereken belgeleri çıkarıp, doldurup, imzalayıp, tarayıp, derleyip toparladıktan sonra noter yolunu tuttum.</p>

<p>Noterde 10 dakika (ve 569 Lira) sonrasında noter yakındaki PTT&#39;ye gidip 62 Lira ödedikten sonra belgeleri postaladım. PTT, İstanbul&#39;da bir tuhaf çalışıyor. 6 gün (4 iş günü) sürdü belgelerin varması. Tersi olsa, Ankara&#39;ya net 1 günde sorunsuz getiriyorlar.</p>

<p>2 Kasım&#39;da DGF&#39;den başka bir arkadaş işlemlere başlandığını, olası gelişmelerden haberdar edeceğini iletiyor. Tabi TAREKS için 500 Lira da buradan gitti (sanırım duruma göre bu paranın iadesini isteyebiliyorum, emin değilim).</p>

<p>5 gün (3 iş günü) sessizlikten sonra, 7 Kasım akşamında, soruyorum bir gelişme oldu mu diye. 8&#39;inin sabahında hemen cevap geliyor: “dün beyanatta bulunduk, öğleye kadar dosya kapanır, öğleden sonra çıkış veririz” diye. Hakikaten de paket öğleden sonra gümrükten çıktı.</p>

<p>Aha bugün 9 Kasım, paket geldi. Paketin bi tarafının etrafı “İncelendi” bantıyla sarılı tabi. Neyse ürünler sağlam ama. Kargo irsaliyesinde DDP, kargo etiketinde DTP yazması da ekstra ironik ;)</p>

<hr>

<p>Buraya kadar hep kibar davranan DHL (ve DGF) görevlilerine teşekkür etmek istiyorum. E-posta ekinin eksik gelmesi sorunu dışında her şey akıcı gerçekleşti. Bu kadar frictionless bir deneyim beklemiyordum şahsen.</p>

<p>DHL Gümrük Portal&#39;ına bakmadıysanız bi bakın derim: <a href="https://gumruk.dhl.com.tr">https://gumruk.dhl.com.tr</a></p>

<p>Kendi gümrük rehberleri de şurada mevcut: <a href="https://gumruk.dhl.com.tr/Content/documents/Gumruk%20Musteri%20Rehberi.pdf">https://gumruk.dhl.com.tr/Content/documents/Gumruk%20Musteri%20Rehberi.pdf</a></p>

<hr>

<p>DGF benden şu belgeleri E-posta ile göndermemi istedi:</p>

<blockquote><ul><li>Dolaylı Temsil Yetki Belgesi <strong>(<ins>Noterden Tasdik Ettirilmez</ins>)</strong> – (Fatura üzerindeki alıcı tarafından doldurulmalı ve imzalanmalıdır),</li>
<li>İthalat Gümrükleme Talimatı (Fatura üzerindeki alıcı tarafından doldurulmalı ve imzalanmalıdır),</li>
<li>Yurdışına yapılan ödemenin K.kartı ekstre görünütüsü veya ödemenin banka uygulaması üzerindeki ekran görünütüsü,</li>
<li>Order Details – Order İnformation görselleri</li>
<li>Kimlik Fotokopisi,</li></ul>
</blockquote>

<p>Dolaylı Temsil Yetki Belgesi ve İthalat Gümrükleme Talimatı ekte olması gerekiyor.</p>

<p>DGF benden şu belgeleri paket TAREKS&#39;e tabii olduğundan dolayı Posta ile ofislerine ulaştırmamı istedi:</p>

<blockquote><ul><li>Gerçek Kişi Adına Kayıt Dilekçesi – İsim Soyisim imzalı</li>
<li>Tareks Taahütnamesi – Noter Tasdikli ( Geçerlilik tarihi minimum 1 sene olmak üzere dilediğiniz tarihe kadar belirlenebilir. [isim gizlendi] ismi ve bilgileri sabit kalmalıdır)</li>
<li>İmza Beyannemesi – Noter Tasdikli (noterden talep edilmelidir)</li>
<li>Vergi Mükellefiyet yazısı – E Devlet <a href="https://dijital.gib.gov.tr/portal/mukellefiyet-borc-durum-yazilarim">https://dijital.gib.gov.tr/portal/mukellefiyet-borc-durum-yazilarim</a> Dilekçelerim&gt;Mükellefiyet/Borç Durum Yazılarım&gt;YENİ TALEP OLUŞTUR&gt;Mükellefiyet Yazısı Talebi&gt;Merkez Adımlarını takip ederek belge oluşturulacaktır</li></ul>
</blockquote>

<hr>

<p><b id="f1" id="f1">1</b>: Burada ufak bi durum var, Incoterms® 2020 ile ortalık karışmış durumda. DHL, (anladığım kadarıyla) Türkiye&#39;de bireysel alıcılar ve/veya göndericiler için “basitleştirilmiş” DTP (Duty Taxes Paid) ve DTU (Duty Taxes Unpaid) terimlerini kullanıyor. <a href="https://www.dhlexpress.nl/en/support/customs/per-country/duty-taxes-paid">DHL, Hollanda&#39;da da bu formatı kullanıyor</a>. UPS, Türkiye&#39;de DDP (Delivery Duty Paid) ve DDU (Delivery Duty Unpaid) kullanıyor diye hatırlıyorum.<a href="#a1">↩</a></p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/mclarenmerch-dhl-gumruk</guid>
      <pubDate>Thu, 09 Nov 2023 09:18:14 +0000</pubDate>
    </item>
    <item>
      <title>Microsoft&#39;un Tuhaf Banka/Şube/İl kodu formatı</title>
      <link>https://blog.linuxgemini.space/microsoftun-tuhaf-banka-sube-il-kodu-formati</link>
      <description>&lt;![CDATA[Microsoft Partner Center&#39;a banka hesabınızı eklerken tuhaf bir havale kodu formatı istiyor, hızlıca formatı göstereyim:!--more--&#xA;&#xA;HSBC Bank A.Ş. - Ankara Bireysel Şubesi için kod aşağıdadır:&#xA;012300060006&#xA;&#xA;Formatın ayrık hali şu şekilde:&#xA;0123 00060 006&#xA;&#xA;0123 : Banka EFT kodu  (https://www.trbanka.com/banka-eft-kodlari/)&#xA;00060: Banka Şube kodu (https://www.trbanka.com/)&#xA;006  : İl Plaka kodu&#xA;&#xA;Kodlar alan uzunluğundan kısa olduğunda başına 0 ekliyorsunuz:&#xA;&#xA;123 --  0123&#xA;60  --  00060&#xA;06  --  006 (Haliyle plaka kodlarımız XX formatında zaten.)&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>Microsoft Partner Center&#39;a banka hesabınızı eklerken tuhaf bir havale kodu formatı istiyor, hızlıca formatı göstereyim:</p>

<pre><code>HSBC Bank A.Ş. - Ankara Bireysel Şubesi için kod aşağıdadır:
012300060006

Formatın ayrık hali şu şekilde:
0123 00060 006

0123 : Banka EFT kodu  (https://www.trbanka.com/banka-eft-kodlari/)
00060: Banka Şube kodu (https://www.trbanka.com/)
006  : İl Plaka kodu

Kodlar alan uzunluğundan kısa olduğunda başına 0 ekliyorsunuz:

123 --&gt; 0123
60  --&gt; 00060
06  --&gt; 006 (Haliyle plaka kodlarımız XX formatında zaten.)
</code></pre>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/microsoftun-tuhaf-banka-sube-il-kodu-formati</guid>
      <pubDate>Sat, 21 Oct 2023 20:26:46 +0000</pubDate>
    </item>
    <item>
      <title>Musings with Quectel EC25-EUX LTE Module</title>
      <link>https://blog.linuxgemini.space/musings-with-quectel-ec25-eux-lte-module</link>
      <description>&lt;![CDATA[So I wanted to add Cellular connectivity to my GL.iNet Slate AX but because of regulations here, I needed to source my LTE module locally.&#xA;&#xA;...After couple months, I finally did.!--more--&#xA;&#xA;At first, I saw an EG25-G USB dongle from EXVIST on Amazon Turkey:&#xA;&#xA;Screenshot of Amazon Turkey, listing the EXVIST USB Dongle, containing the Quectel EG25-G chip.&#xA;&#xA;But, I remembered the entire IMEI Allowlist shenanigans after it arrived to me. So I started to play with it carefully, considering that I might return it soon.&#xA;&#xA;Then I decided to look at EXVIST&#39;s own website, and found out that they sell configurable USB carrier board enclosures for Quectel mini-PCIe cards as well:&#xA;&#xA;Screenshot of EXVIST&#39;s website, showing their &#34;IoT Dongles&#34;.&#xA;&#xA;You might ask &#34;mini-PCIe and USB? What?&#34; and that&#39;s a valid question. Here&#39;s a fun tidbit, mini-PCIe spec actually has pins for direct USB 2.0 connection which Quectel actually markets this as an option on their product brochures.&#xA;&#xA;The carrier board utilizes this and the other &#34;reserved&#34; pins for SIM card itself, here&#39;s a pinout from SixFab, where they also use USB D+ and D- pins (emphasis mine):&#xA;&#xA;A pinout of mini-PCIe head, marking USB DP and DM as red.&#xA;&#xA;I immediately jumped onto Amazon Turkey and yep, the bare carrier enclosure is available to buy:&#xA;&#xA;Screenshot of Amazon Turkey, listing the EXVIST USB carrier enclosure.&#xA;&#xA;In the meantime, I looked at local e-commerce marketplaces other than Amazon, and I found an EC25-EUX on Trendyol:&#xA;&#xA;Screenshot of Trendyol, showing a listing of the Quectel EC25-EUX mini-PCIe module.&#xA;&#xA;To be extra sure, I asked the seller if the IMEIs of the stock they have are registered and they said yes:&#xA;&#xA;Screenshot of Trendyol, showing the &#34;Questions to Seller&#34; portion of the EC25-EUX module listing.&#xA;&#xA;You can guess that I immediately bought the module.&#xA;&#xA;I started the return procedure of the EG25-G dongle and sent it away. I got the EC25-EUX module next day and the carrier enclosure arrived a week later.&#xA;&#xA;First two cons:&#xA;&#xA;  The status LED is blue. It is very bright.&#xA;  It has mounting flaps on the sides. If you want to carry this as an extension to your travel connectivity pack, you need to carefully Dremel out the flaps.&#xA;&#xA;Now, let&#39;s get to how the software stuff up to speed.&#xA;&#xA;I need to applaud EXVIST, because unlike Quectel themselves, they actually provide open documentation to do things:&#xA;&#xA;Screenshot of EXVIST&#39;s documentation page, which they use GitBook.&#xA;&#xA;You can grab the drivers at https://docs.exvist.com/dongle/ts/drivers.&#xA;&#xA;Looking at the tools page, you will see two tools:&#xA;&#xA;  Quectel&#39;s QCOM: It is a bulk configuration GUI tool which utilizes AT commands.&#xA;  Quectel&#39;s QNavigator: It is a GUI tool to manage your module (also uses AT commands). It also contains QCOM as a separate window inside the app.&#xA;&#xA;Both tools will document the AT commands issued.&#xA;&#xA;There will be 4 interfaces coming up when you plug the module in (gonna be using Linux paths):&#xA;&#xA;  /dev/ttyUSB0: the &#34;DM&#34; interface, apparently its Qualcomm&#39;s QXDM. &#xA;  /dev/ttyUSB1: the NMEA/GNSS interface, which we don&#39;t use (because this is GPS, as you might have noticed).&#xA;  /dev/ttyUSB2: the direct AT interface, you can manage your modem from this.&#xA;  /dev/ttyUSB3: the AT modem interface, which Windows utilizes it as a network interface (It is the last COM port), so it is invisible. I assume Windows also does QMI from here, so you need to do the settings I mention below for proper Windows support as well.&#xA;  /dev/cdc-wdm0: this is the direct QMI. It will use the (open-source) qmiwwan or the (proprietary) GobiNet driver.&#xA;&#xA;To &#34;&#34;&#34;properly&#34;&#34;&#34; use your module on OpenWrt based systems (aka &#34;using the /dev/cdc-wdm0 interface&#34;), you need to have some prerequisites, which SixFab helpfully provides it:&#xA;&#xA;  Check if the modem is configured correctly by sending the AT+QCFG=&#34;usbnet&#34; command. It should return 0.&#xA;  If the command result shows a digit other than 0 at the end, set the option to 0 by sending the AT+QCFG=&#34;usbnet&#34;,0 command.&#xA;  Wait for 10 seconds and reboot the module by sending the AT+CFUN=1,1 command.&#xA;&#xA;If your system allows a protocol named &#34;QCI&#34; alongside &#34;QMI&#34;, you can use that for your Quectel module.&#xA;&#xA;I&#39;m still messing around with this, I hope I remember to update this post with further information (Written in 2023-09-27).&#xA;&#xA;2023-09-28 Update:&#xA;&#xA;Looking at OpenWrt Docs, I have found out what each usbnet settings mean:&#xA;&#xA;AT+QCFG=&#34;usbnet&#34;&#x9;# check the current mode&#xA;AT+QCFG=&#34;usbnet&#34;,0&#x9;# set QMI or RMNET mode&#xA;AT+QCFG=&#34;usbnet&#34;,1&#x9;# set ECM mode&#xA;AT+QCFG=&#34;usbnet&#34;,2&#x9;# set MBIM mode&#xA;AT+QCFG=&#34;usbnet&#34;,3&#x9;# set RNDIS mode&#xA;&#xA;It is weird that Quectel doesn&#39;t mention any of this in their own AT documentation. Apparently they do, its just in a separate file.&#xA;&#xA;To make things extra spicy, my modem had this set to 3, which I don&#39;t know what that means. I have updated the list above.&#xA;&#xA;2023-10-02 Update:&#xA;&#xA;I&#39;ve been trying to get the module work on macOS, but it seems like I won&#39;t be able to without modifying Apple&#39;s own support kexts.&#xA;&#xA;To make sure the module actually gets loaded requires me to use AppleWWANSupport or AppleWWANSupport1 driver kexts, but they have their own vendor ID list, which needs to include Quectel&#39;s vendor ID. And they obviously don&#39;t.&#xA;&#xA;2023-11-01 Update:&#xA;&#xA;I&#39;ve been testing the module with my GL.iNet Slate AX for more than a month at this point and with the usbnet mode set to 0 (QMI/RMNET) the modem is pretty much plug and play:&#xA;&#xA;Screenshot of the GL.iNet Slate AX management interface.&#xA;&#xA;2025-01-26 Update:&#xA;&#xA;&#34;macOS support&#34; has been lingering in my head ever since I failed to get native support working. Then recently I stumbled upon Quectel staff responding to my request last year:&#xA;&#xA;Bean Wang of Quectel responding: &#34;I think the macOS might support the ECM.&#34;&#xA;&#xA;So it turns out ECM is called &#34;Ethernet Control Model&#34; and it is basically the modem emulating an USB ethernet card with a NAT&#39;ed network connected.&#xA;&#xA;This model is natively available on both macOS and Linux. Windows requires additional drivers.&#xA;&#xA;Setting it up is quite simple, run the following command through the AT interface (via a Windows or Linux device):&#xA;&#xA;AT+QCFG=&#34;usbnet&#34;,1&#xA;&#xA;SixFab has a support document for their SIM service at https://docs.sixfab.com/page/cellular-internet-connection-in-ecm-mode&#xA;&#xA;With this figured out, I replied to the Quectel forum post:&#xA;&#xA;My reply forum post&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>So I wanted to add Cellular connectivity to my GL.iNet <a href="https://www.gl-inet.com/products/gl-axt1800/">Slate AX</a> but <a href="https://en.wikipedia.org/wiki/International_Mobile_Equipment_Identity#Allowlists">because of regulations here</a>, I needed to source my LTE module locally.</p>

<p>...After couple months, I finally did.</p>

<p>At first, I saw an <a href="https://www.exvist.com/products/4g-lte-usb-dongle-wquectel-iot-eg25-g-lcc-sim-slot">EG25-G USB dongle from EXVIST</a> on <a href="https://www.amazon.com.tr/dp/B096VSHXSP">Amazon Turkey</a>:</p>

<p><img src="https://b2.ilter.is/a/4fc5cdfce/3809/WinCap_2023-09-28_010054.png" alt="Screenshot of Amazon Turkey, listing the EXVIST USB Dongle, containing the Quectel EG25-G chip."></p>

<p><em>But,</em> I remembered the entire IMEI Allowlist shenanigans <em>after</em> it arrived to me. So I started to play with it carefully, considering that I might return it soon.</p>

<p>Then I decided to look at <a href="https://www.exvist.com/">EXVIST&#39;s own website</a>, and found out that they sell <a href="https://www.exvist.com/collections/iot-dongle">configurable USB carrier board enclosures for Quectel mini-PCIe cards</a> as well:</p>

<p><img src="https://b2.ilter.is/a/907483ed5/2703/WinCap_2023-09-28_010546.png" alt="Screenshot of EXVIST&#39;s website, showing their &#34;IoT Dongles&#34;."></p>

<p>You might ask “mini-PCIe and USB? What?” and that&#39;s a valid question. Here&#39;s a fun tidbit, mini-PCIe spec actually has pins for direct USB 2.0 connection which Quectel actually markets this as an option on their product brochures.</p>

<p>The carrier board utilizes this and the other “reserved” pins for SIM card itself, here&#39;s a pinout from SixFab, where they also use USB D+ and D- pins (emphasis mine):</p>

<p><img src="https://b2.ilter.is/a/98909d369/8af7/WinCap_2023-09-28_011301.png" alt="A pinout of mini-PCIe head, marking USB DP and DM as red."></p>

<p>I immediately jumped onto Amazon Turkey and yep, <a href="https://www.amazon.com.tr/dp/B08GFNWHNC">the bare carrier enclosure is available to buy</a>:</p>

<p><img src="https://b2.ilter.is/a/cc9565253/30d7/WinCap_2023-09-28_010716.png" alt="Screenshot of Amazon Turkey, listing the EXVIST USB carrier enclosure."></p>

<p>In the meantime, I looked at local e-commerce marketplaces <em>other than</em> Amazon, and I found an <a href="https://www.trendyol.com/quectel/ec25-eux-128-sgns-4g-lte-mini-pcie-modul-p-755956634?boutiqueId=61&amp;merchantId=166738">EC25-EUX on Trendyol</a>:</p>

<p><img src="https://b2.ilter.is/a/5c9fd38c5/235c/WinCap_2023-09-28_001523.png" alt="Screenshot of Trendyol, showing a listing of the Quectel EC25-EUX mini-PCIe module."></p>

<p>To be extra sure, I asked the seller if the IMEIs of the stock they have are registered and they said yes:</p>

<p><img src="https://b2.ilter.is/a/cd7646ba1/1233/WinCap_2023-09-28_011811.png" alt="Screenshot of Trendyol, showing the &#34;Questions to Seller&#34; portion of the EC25-EUX module listing."></p>

<p>You can guess that I immediately bought the module.</p>

<p>I started the return procedure of the EG25-G dongle and sent it away. I got the EC25-EUX module next day and the carrier enclosure arrived a week later.</p>

<p>First two cons:</p>
<ul><li>The status LED is blue. It is <strong><em>very bright</em></strong>.</li>
<li>It has mounting flaps on the sides. If you want to carry this as an extension to your travel connectivity pack, you need to <em>carefully</em> Dremel out the flaps.</li></ul>

<p>Now, let&#39;s get to how the software stuff up to speed.</p>

<p>I need to applaud EXVIST, because unlike Quectel themselves, <a href="https://docs.exvist.com/dongle/">they actually provide open documentation to do things</a>:</p>

<p><img src="https://b2.ilter.is/a/fd70e841a/9820/WinCap_2023-09-28_012619.png" alt="Screenshot of EXVIST&#39;s documentation page, which they use GitBook."></p>

<p>You can grab the drivers at <a href="https://docs.exvist.com/dongle/ts/drivers">https://docs.exvist.com/dongle/ts/drivers</a>.</p>

<p>Looking at the <a href="https://docs.exvist.com/dongle/ts/tools">tools page</a>, you will see two tools:</p>
<ul><li>Quectel&#39;s QCOM: It is a bulk configuration GUI tool which utilizes AT commands.</li>
<li>Quectel&#39;s QNavigator: It is a GUI tool to manage your module (also uses AT commands). It also contains QCOM as a separate window inside the app.</li></ul>

<p>Both tools will document the AT commands issued.</p>

<p>There will be 4 interfaces coming up when you plug the module in (gonna be using Linux paths):</p>
<ul><li><code>/dev/ttyUSB0</code>: the “DM” interface, apparently its Qualcomm&#39;s QXDM.</li>
<li><code>/dev/ttyUSB1</code>: the NMEA/GNSS interface, which we don&#39;t use (because this is GPS, as you might have noticed).</li>
<li><code>/dev/ttyUSB2</code>: the direct AT interface, you can manage your modem from this.</li>
<li><code>/dev/ttyUSB3</code>: the AT modem interface, which Windows utilizes it as a network interface (It is the <em>last</em> COM port), so it is invisible. I assume Windows also does QMI from here, so you need to do the settings I mention below for proper Windows support as well.</li>
<li><code>/dev/cdc-wdm0</code>: this is the direct QMI. It will use the (open-source) <code>qmi_wwan</code> or the (proprietary) <code>GobiNet</code> driver.</li></ul>

<p>To “”“properly”“” use your module on OpenWrt based systems (aka “using the <code>/dev/cdc-wdm0</code> interface”), you need to have some prerequisites, <a href="https://docs.sixfab.com/page/setting-up-a-data-connection-over-qmi-interface-using-libqmi">which SixFab helpfully provides it</a>:</p>
<ul><li>Check if the modem is configured correctly by sending the <code>AT+QCFG=&#34;usbnet&#34;</code> command. It should return 0.</li>
<li>If the command result shows a digit other than 0 at the end, set the option to 0 by sending the <code>AT+QCFG=&#34;usbnet&#34;,0</code> command.</li>
<li>Wait for 10 seconds and reboot the module by sending the <code>AT+CFUN=1,1</code> command.</li></ul>

<p>If your system allows a protocol named “QCI” alongside “QMI”, you can use that for your Quectel module.</p>

<p>I&#39;m still messing around with this, I hope I remember to update this post with further information (Written in 2023-09-27).</p>

<p><strong><em>2023-09-28 Update:</em></strong></p>

<p>Looking at <a href="https://openwrt.org/docs/guide-user/network/wan/wwan/ltedongle#lte_or_5g_modem_preparation">OpenWrt Docs</a>, I have found out what each <code>usbnet</code> settings mean:</p>

<pre><code>AT+QCFG=&#34;usbnet&#34;	# check the current mode
AT+QCFG=&#34;usbnet&#34;,0	# set QMI or RMNET mode
AT+QCFG=&#34;usbnet&#34;,1	# set ECM mode
AT+QCFG=&#34;usbnet&#34;,2	# set MBIM mode
AT+QCFG=&#34;usbnet&#34;,3	# set RNDIS mode
</code></pre>

<p><del>It is weird that Quectel doesn&#39;t mention any of this in their own AT documentation.</del> Apparently they do, <a href="https://www.quectel.com/wp-content/uploads/2022/06/Quectel_EC2xEG2xEG9xEM05_Series_QCFG_AT_Commands_Manual_V1.1.pdf">its just in a separate file</a>.</p>

<p><del>To make things extra spicy, my modem had this set to <code>3</code>, which I don&#39;t know what that means.</del> I have updated the list above.</p>

<p><strong><em>2023-10-02 Update:</em></strong></p>

<p><del>I&#39;ve been trying to get the module work on macOS, but it seems like I won&#39;t be able to without modifying Apple&#39;s own support kexts.</del></p>

<p><del>To make sure the module actually gets loaded requires me to use AppleWWANSupport or AppleWWANSupport1 driver kexts, but they have their own vendor ID list, which needs to include Quectel&#39;s vendor ID. And they obviously don&#39;t.</del></p>

<p><strong><em>2023-11-01 Update:</em></strong></p>

<p>I&#39;ve been testing the module with my <a href="https://www.gl-inet.com/products/gl-axt1800/">GL.iNet Slate AX</a> for more than a month at this point and with the <code>usbnet</code> mode set to <code>0</code> (QMI/RMNET) the modem is pretty much plug and play:</p>

<p><img src="https://b2.ilter.is/a/899e81534/fb9a/WinCap_2023-11-03_052001.png" alt="Screenshot of the GL.iNet Slate AX management interface."></p>

<p><strong><em>2025-01-26 Update:</em></strong></p>

<p>“macOS support” has been lingering in my head ever since I failed to get native support working. Then recently I stumbled upon Quectel staff <em>responding</em> to my request last year:</p>

<p><img src="https://b2.ilter.is/a/3aa91220a/1fe9/WinCap_2025-01-26_192646.png" alt="Bean Wang of Quectel responding: &#34;I think the macOS might support the ECM.&#34;"></p>

<p>So it turns out ECM is called “Ethernet Control Model” and it is basically the modem emulating an USB ethernet card with a NAT&#39;ed network connected.</p>

<p>This model is natively available on both macOS and Linux. Windows requires additional drivers.</p>

<p>Setting it up is quite simple, run the following command through the AT interface (via a Windows or Linux device):</p>

<pre><code>AT+QCFG=&#34;usbnet&#34;,1
</code></pre>

<p>SixFab has a support document for their SIM service at <a href="https://docs.sixfab.com/page/cellular-internet-connection-in-ecm-mode">https://docs.sixfab.com/page/cellular-internet-connection-in-ecm-mode</a></p>

<p><a href="https://forums.quectel.com/t/ec25-driver-for-mac-os/29834/5?u=linuxgemini">With this figured out, I replied to the Quectel forum post</a>:</p>

<p><img src="https://b2.ilter.is/a/c9c163687/1946/WinCap_2025-01-26_193332.png" alt="My reply forum post"></p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/musings-with-quectel-ec25-eux-lte-module</guid>
      <pubDate>Wed, 27 Sep 2023 22:08:40 +0000</pubDate>
    </item>
    <item>
      <title>Dialplan of Turkey, adjusted for FreePBX</title>
      <link>https://blog.linuxgemini.space/dialplan-of-turkey-adjusted-for-freepbx</link>
      <description>&lt;![CDATA[(this was a private gist i authored 7 months ago, making it public to those who want)&#xA;&#xA;The up-to-date plan is available on https://www.btk.gov.tr/genel-numaralandirma-plani though Some Assembly Is Required™️&#xA;&#xA;The pre-assembled version is available below.!--more--&#xA;&#xA;Taşıyıcı seçim kodları&#xA;Türk Telekomünikasyon A.Ş. ve STH işletmecileri taşıyıcı seçim kodları&#xA;10ZN&#xA;&#xA;Kısa Numaralar&#xA;Kamu kurumlarına tahsisli kısa numaralar&#xA;1ZX&#xA;&#xA;Coğrafi numaralar&#xA;Batı Anadolu illeri coğrafi alan kodları&#xA;2XXXXXXXXX&#xA;&#xA;Orta Anadolu illeri coğrafi alan kodları&#xA;3XXXXXXXXX&#xA;&#xA;Doğu Anadolu illeri coğrafi alan kodları&#xA;4XXXXXXXXX&#xA;&#xA;Mobil numaralar&#xA;TT Mobil İletişim Hizmetleri A.Ş.’ye tahsisli alan kodları&#xA;50[15-7]XXXXXXX&#xA;&#xA;SMŞH için belirlenmiş mobil numaralar&#xA;510XXXXXXX&#xA;516XXXXXXX&#xA;561XXXXXXX&#xA;&#xA;Türk Telekomünikasyon A.Ş.’ye tahsisli çağrı hizmeti numaraları&#xA;512XXXXXXX&#xA;&#xA;Turkcell İletişim Hizmetleri A.Ş.’ye tahsisli alan kodları&#xA;53XXXXXXXX&#xA;&#xA;Vodafone Telekomünikasyon A.Ş.’ye tahsisli alan kodları&#xA;54XXXXXXXX&#xA;&#xA;TT Mobil İletişim Hizmetleri A.Ş.’ye tahsisli alan kodları&#xA;55[1-59]XXXXXXX&#xA;&#xA;Globalstar A.Ş. ’ye tahsisli GMPCS mobil telefon hizmeti numaraları (2110000-2120306, ve 4610000-4619999 arasındaki 20.307 numara)&#xA;592211XXXX&#xA;5922120[0-2]XX&#xA;592212030[0-6]&#xA;592461XXXX&#xA;&#xA;TCDD ’ye tahsisli GSM-R numaraları (8100000-8109999 arasındaki 10.000 numara)&#xA;594810XXXX&#xA;&#xA;Coğrafi Olmayan Numaralar&#xA;Ücretsiz aranır numaralar&#xA;800XXXXXXX&#xA;&#xA;STH iki kademeli arama yöntemi erişim numaraları&#xA;811XXXXXXX&#xA;&#xA;İSS hizmeti çevirmeli (dial-up) bağlantı erişim numaraları&#xA;822XXXXXXX&#xA;&#xA;Konumdan Bağımsız Numaralar&#xA;850XXXXXXX&#xA;&#xA;Katma değerli hizmet numaraları (özel içerikli ve cinsel içerikli hizmetler dışında kalan hizmetler)&#xA;888XXXXXXX&#xA;&#xA;Katma değerli hizmet numaraları (özel içerikli hizmetler)&#xA;898XXXXXXX&#xA;&#xA;Katma değerli hizmet numaraları (cinsel içerikli hizmetler)&#xA;900XXXXXXX&#xA;&#xA;Rehberlik Hizmeti Numaraları&#xA;118ZX&#xA;&#xA;(out-of-plan) Özel Servis Numaraları (444)&#xA;444XXXX&#xA;&#xA;(out-of-plan) İl İçi Sabit Telefonlar&#xA;XXXXXXX&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p>(this was a private gist i authored 7 months ago, making it public to those who want)</p>

<p>The up-to-date plan is available on <a href="https://www.btk.gov.tr/genel-numaralandirma-plani">https://www.btk.gov.tr/genel-numaralandirma-plani</a> though Some Assembly Is Required™️</p>

<p>The pre-assembled version is available below.</p>

<h2 id="taşıyıcı-seçim-kodları" id="taşıyıcı-seçim-kodları">Taşıyıcı seçim kodları</h2>

<h3 id="türk-telekomünikasyon-a-ş-ve-sth-işletmecileri-taşıyıcı-seçim-kodları" id="türk-telekomünikasyon-a-ş-ve-sth-işletmecileri-taşıyıcı-seçim-kodları">Türk Telekomünikasyon A.Ş. ve STH işletmecileri taşıyıcı seçim kodları</h3>

<pre><code>10ZN
</code></pre>

<h2 id="kısa-numaralar" id="kısa-numaralar">Kısa Numaralar</h2>

<h3 id="kamu-kurumlarına-tahsisli-kısa-numaralar" id="kamu-kurumlarına-tahsisli-kısa-numaralar">Kamu kurumlarına tahsisli kısa numaralar</h3>

<pre><code>1ZX
</code></pre>

<h2 id="coğrafi-numaralar" id="coğrafi-numaralar">Coğrafi numaralar</h2>

<h3 id="batı-anadolu-illeri-coğrafi-alan-kodları" id="batı-anadolu-illeri-coğrafi-alan-kodları">Batı Anadolu illeri coğrafi alan kodları</h3>

<pre><code>2XXXXXXXXX
</code></pre>

<h3 id="orta-anadolu-illeri-coğrafi-alan-kodları" id="orta-anadolu-illeri-coğrafi-alan-kodları">Orta Anadolu illeri coğrafi alan kodları</h3>

<pre><code>3XXXXXXXXX
</code></pre>

<h3 id="doğu-anadolu-illeri-coğrafi-alan-kodları" id="doğu-anadolu-illeri-coğrafi-alan-kodları">Doğu Anadolu illeri coğrafi alan kodları</h3>

<pre><code>4XXXXXXXXX
</code></pre>

<h2 id="mobil-numaralar" id="mobil-numaralar">Mobil numaralar</h2>

<h3 id="tt-mobil-iletişim-hizmetleri-a-ş-ye-tahsisli-alan-kodları" id="tt-mobil-iletişim-hizmetleri-a-ş-ye-tahsisli-alan-kodları">TT Mobil İletişim Hizmetleri A.Ş.’ye tahsisli alan kodları</h3>

<pre><code>50[15-7]XXXXXXX
</code></pre>

<h3 id="smşh-için-belirlenmiş-mobil-numaralar" id="smşh-için-belirlenmiş-mobil-numaralar">SMŞH için belirlenmiş mobil numaralar</h3>

<pre><code>510XXXXXXX
516XXXXXXX
561XXXXXXX
</code></pre>

<h3 id="türk-telekomünikasyon-a-ş-ye-tahsisli-çağrı-hizmeti-numaraları" id="türk-telekomünikasyon-a-ş-ye-tahsisli-çağrı-hizmeti-numaraları">Türk Telekomünikasyon A.Ş.’ye tahsisli çağrı hizmeti numaraları</h3>

<pre><code>512XXXXXXX
</code></pre>

<h3 id="turkcell-iletişim-hizmetleri-a-ş-ye-tahsisli-alan-kodları" id="turkcell-iletişim-hizmetleri-a-ş-ye-tahsisli-alan-kodları">Turkcell İletişim Hizmetleri A.Ş.’ye tahsisli alan kodları</h3>

<pre><code>53XXXXXXXX
</code></pre>

<h3 id="vodafone-telekomünikasyon-a-ş-ye-tahsisli-alan-kodları" id="vodafone-telekomünikasyon-a-ş-ye-tahsisli-alan-kodları">Vodafone Telekomünikasyon A.Ş.’ye tahsisli alan kodları</h3>

<pre><code>54XXXXXXXX
</code></pre>

<h3 id="tt-mobil-iletişim-hizmetleri-a-ş-ye-tahsisli-alan-kodları-1" id="tt-mobil-iletişim-hizmetleri-a-ş-ye-tahsisli-alan-kodları-1">TT Mobil İletişim Hizmetleri A.Ş.’ye tahsisli alan kodları</h3>

<pre><code>55[1-59]XXXXXXX
</code></pre>

<h3 id="globalstar-a-ş-ye-tahsisli-gmpcs-mobil-telefon-hizmeti-numaraları-2110000-2120306-ve-4610000-4619999-arasındaki-20-307-numara" id="globalstar-a-ş-ye-tahsisli-gmpcs-mobil-telefon-hizmeti-numaraları-2110000-2120306-ve-4610000-4619999-arasındaki-20-307-numara">Globalstar A.Ş. ’ye tahsisli GMPCS mobil telefon hizmeti numaraları (2110000-2120306, ve 4610000-4619999 arasındaki 20.307 numara)</h3>

<pre><code>592211XXXX
5922120[0-2]XX
592212030[0-6]
592461XXXX
</code></pre>

<h3 id="tcdd-ye-tahsisli-gsm-r-numaraları-8100000-8109999-arasındaki-10-000-numara" id="tcdd-ye-tahsisli-gsm-r-numaraları-8100000-8109999-arasındaki-10-000-numara">TCDD ’ye tahsisli GSM-R numaraları (8100000-8109999 arasındaki 10.000 numara)</h3>

<pre><code>594810XXXX
</code></pre>

<h2 id="coğrafi-olmayan-numaralar" id="coğrafi-olmayan-numaralar">Coğrafi Olmayan Numaralar</h2>

<h3 id="ücretsiz-aranır-numaralar" id="ücretsiz-aranır-numaralar">Ücretsiz aranır numaralar</h3>

<pre><code>800XXXXXXX
</code></pre>

<h3 id="sth-iki-kademeli-arama-yöntemi-erişim-numaraları" id="sth-iki-kademeli-arama-yöntemi-erişim-numaraları">STH iki kademeli arama yöntemi erişim numaraları</h3>

<pre><code>811XXXXXXX
</code></pre>

<h3 id="iss-hizmeti-çevirmeli-dial-up-bağlantı-erişim-numaraları" id="iss-hizmeti-çevirmeli-dial-up-bağlantı-erişim-numaraları">İSS hizmeti çevirmeli (dial-up) bağlantı erişim numaraları</h3>

<pre><code>822XXXXXXX
</code></pre>

<h3 id="konumdan-bağımsız-numaralar" id="konumdan-bağımsız-numaralar">Konumdan Bağımsız Numaralar</h3>

<pre><code>850XXXXXXX
</code></pre>

<h3 id="katma-değerli-hizmet-numaraları-özel-içerikli-ve-cinsel-içerikli-hizmetler-dışında-kalan-hizmetler" id="katma-değerli-hizmet-numaraları-özel-içerikli-ve-cinsel-içerikli-hizmetler-dışında-kalan-hizmetler">Katma değerli hizmet numaraları (özel içerikli ve cinsel içerikli hizmetler dışında kalan hizmetler)</h3>

<pre><code>888XXXXXXX
</code></pre>

<h3 id="katma-değerli-hizmet-numaraları-özel-içerikli-hizmetler" id="katma-değerli-hizmet-numaraları-özel-içerikli-hizmetler">Katma değerli hizmet numaraları (özel içerikli hizmetler)</h3>

<pre><code>898XXXXXXX
</code></pre>

<h3 id="katma-değerli-hizmet-numaraları-cinsel-içerikli-hizmetler" id="katma-değerli-hizmet-numaraları-cinsel-içerikli-hizmetler">Katma değerli hizmet numaraları (cinsel içerikli hizmetler)</h3>

<pre><code>900XXXXXXX
</code></pre>

<h2 id="rehberlik-hizmeti-numaraları" id="rehberlik-hizmeti-numaraları">Rehberlik Hizmeti Numaraları</h2>

<pre><code>118ZX
</code></pre>

<h2 id="out-of-plan-özel-servis-numaraları-444" id="out-of-plan-özel-servis-numaraları-444">(out-of-plan) Özel Servis Numaraları (444)</h2>

<pre><code>444XXXX
</code></pre>

<h2 id="out-of-plan-il-içi-sabit-telefonlar" id="out-of-plan-il-içi-sabit-telefonlar">(out-of-plan) İl İçi Sabit Telefonlar</h2>

<pre><code>XXXXXXX
</code></pre>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/dialplan-of-turkey-adjusted-for-freepbx</guid>
      <pubDate>Sat, 15 Jul 2023 15:20:45 +0000</pubDate>
    </item>
    <item>
      <title>Yapı Kredi&#39;den SIM blokesi kaldırdıktan sonra sadece 3DS SMSleri gelmiyorsa...</title>
      <link>https://blog.linuxgemini.space/ykb-3ds-sim-bloke</link>
      <description>&lt;![CDATA[https://acs.yapikredi.com.tr/TDSecureTroy/enrollment üzerinden bloke kaldırma/bilgi güncelleme yapabilirsiniz.!--more--&#xA;&#xA;Bir arkadaşım, müşteri hizmetleriyle yaptığı kırk takla sonucunda bu sayfanın içinde olduğunu öğrendi.&#xA;&#xA;Tabi fark etmek için yine detaylı okumanız gerekiyor.&#xA;&#xA;hr style=&#34;color:#9300ff;background-color:#9300ff&#34; /hr&#xD;&#xA;br&#xD;&#xA;subsupCopyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present./sup/sub]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://acs.yapikredi.com.tr/TDSecureTroy/enrollment">https://acs.yapikredi.com.tr/TDSecureTroy/enrollment</a> üzerinden bloke kaldırma/bilgi güncelleme yapabilirsiniz.</p>

<p>Bir arkadaşım, müşteri hizmetleriyle yaptığı kırk takla sonucunda <a href="https://worldcard.com.tr/world-dunyasi/guvenli-alisveris/3d-secure">bu sayfanın</a> içinde olduğunu öğrendi.</p>

<p>Tabi fark etmek için yine detaylı okumanız gerekiyor.</p>

<p><img src="https://btw.i-use-ar.ch/i/2ewb6j30.png" alt=""></p>

<p><hr style="color:#9300ff;background-color:#9300ff"> </hr>
<br>
<sub><sup>Copyright 2018-2026, linuxgemini (İlteriş Yağıztegin Eroğlu). Any and all opinions listed here are my own and not representative of my employers; future, past and present.</sup></sub></p>
]]></content:encoded>
      <guid>https://blog.linuxgemini.space/ykb-3ds-sim-bloke</guid>
      <pubDate>Sat, 15 Apr 2023 18:15:00 +0000</pubDate>
    </item>
  </channel>
</rss>