<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>https on Digi Hunch</title><link>https://www.digihunch.com/tag/https/</link><description>Recent content in https on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Mon, 12 May 2025 23:28:25 -0400</lastBuildDate><atom:link href="https://www.digihunch.com/tag/https/index.xml" rel="self" type="application/rss+xml"/><item><title>WordPress Security Basics</title><link>https://www.digihunch.com/2023/11/wordpress-security/</link><pubDate>Fri, 17 Nov 2023 12:02:00 -0400</pubDate><guid>https://www.digihunch.com/2023/11/wordpress-security/</guid><description>&lt;img src="https://www.digihunch.com/wp-content/uploads/2025/04/feature-wp-basic.webp" alt="Featured image of post WordPress Security Basics" /&gt;&lt;h2 class="wp-block-heading"&gt;Background&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In 2019, I moved &lt;a href="https://www.digihunch.com/2019/04/build-a-wordpress-site-in-one-hour-with-lightsail/"&gt;this site&lt;/a&gt; to WordPress hosted on an Amazon Lightsail instance. There were few visits at that time so I lived with the single-server architecture. The website traffic has since been in steady growth but I have been too busy to catch up with the WordPress security setup. In July 2023, a malware impacted this site as well as the web traffic. It took me several months to fix a few related issues but the traffic still has not fully recovered. This post is about the lessons.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;The Incident&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;I first noticed the issue when I clicked on links to my web page from Google result and got redirected to some spam site. It did not happen 100% of time, but it is annoying enough. In the mean time, from Google search analytics I noticed traffic volume going up with a lot of traffic going to URLs that I did not recognize or create. Somehow these URLs have a lot of clicks and impression counts. These are signs of artificial traffic.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" width="730" height="536" src="https://www.digihunch.com/wp-content/uploads/2023/11/wp-traffic.webp" alt="" class="wp-image-12965" style="width:508px;height:auto" srcset="https://www.digihunch.com/wp-content/uploads/2023/11/wp-traffic.webp 730w, https://www.digihunch.com/wp-content/uploads/2023/11/wp-traffic-300x220.webp 300w" sizes="auto, (max-width: 730px) 100vw, 730px" /&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Obviously the site was hacked. The first thing to determine is whether the server access was compromised. From the audit log (/var/log/auth.log and auth.log.gz) I can see a lot of brute force attempts to connect but fortunately none was successful. That also prompt me to change the default SSH port and use ECDSA key pair. Since the OS access is safe, the hack happens at the WordPress level. I suspected the sideloaded plugins from a few days ago. So I immediately removed all sideloaded plugins. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The attack is called malicious redirect. The plugin puts creepy pages in WordPress directory without my awareness and direct user traffic via my website. To clean up the damage, I looked into my WordPress directories at &lt;code&gt;/opt/bitnami/wordpress&lt;/code&gt; and found many suspicious signs:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;There are directories with weird names, such as &lt;code&gt;rexall-vitalmin&lt;/code&gt;, or &lt;code&gt;q4lee3&lt;/code&gt;, etc&lt;/li&gt;&#10;&lt;li&gt;In each of those directories there was an &lt;code&gt;index.php&lt;/code&gt; file and &lt;code&gt;.htaccess&lt;/code&gt; file; &lt;/li&gt;&#10;&lt;li&gt;Those directories also have other files which look like red herrings;&lt;/li&gt;&#10;&lt;li&gt;All those files have the same date time (from July 6);&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Other directories to look at are &lt;code&gt;/bitnami/wordpress/wp-content/plugins&lt;/code&gt;, where I noticed two directories (named &lt;code&gt;gokyfozaxy&lt;/code&gt; and &lt;code&gt;q199n071&lt;/code&gt;) that are not accounted for; and &lt;code&gt;/bitnami/wordpress/wp-content/themes/&lt;/code&gt;, which contains unknown directories.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Clean up and hardening&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In one of the .htaccess file I noticed segments of mojibake (garbled texts). I first tried to manually remove those files, but the problems stayed. Because the malicious redirect did not happen consistently on every single click, I sometime had false impression that the problem went away. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;However, the challenges with manual cleaning are: 1. there are too many bad files (.htaccess and php files containing mojibake segments); 2. some existing files are impacted with mojibake segments too. I found a free plugin called &lt;a href="https://www.wordfence.com/"&gt;WordFence&lt;/a&gt; to scan the file directory for malicious chagnes, and delete the bad files or bad segments. I also tried a paid scanner (&lt;a href="https://www.malcare.com/"&gt;Malcare&lt;/a&gt;) which found an bad file in /bitnami/wordpress/wp-content/themes/. However, it also blocked my site so I removed Malcare right away. Using the combination of WordFence and Malcare appears to have cleared up the offending files. After restarting apache, the bad URLs are no longer redirecting to spam sites.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This time, I decided to harden the WordPress system given the evidence of brute force attack at different point of entries. At OS level, I mentioned the changes to SSH daemon configuration. At WordPress level, I used WordFence to perform several levels of scans for problems and and improved posture such as admin user&amp;#8217;s MFA. I also noticed a few unrecognized wordpress users and used wordpress CLI to delete those and other unused users.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The wordpress.org website has some &lt;a href="https://wordpress.org/documentation/article/faq-my-site-was-hacked/"&gt;general guidance&lt;/a&gt; on what to do when a site is hacked, and a &lt;a href="https://wordpress.org/documentation/article/hardening-wordpress/"&gt;general guidance&lt;/a&gt; on hardening WordPress.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Back Links&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Another clean up work I had to do is dealing with back links. Back links are URLs from other sites that references this site. There are several situations:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;If it&amp;#8217;s a made-up URL, then it returns 404. In my case, these are URLs that stopped working once I cleaned up my server from the incident. However, the sources are still using these bad URLs. They are bad back-links;&lt;/li&gt;&#10;&lt;li&gt;If it&amp;#8217;s a legit URL, look at if it&amp;#8217;s hot linking, such as another site directly access an image from my site. These are bad back-links;&lt;/li&gt;&#10;&lt;li&gt;If it&amp;#8217;s legit URLs, and the referrer site has a good &lt;a href="https://en.wikipedia.org/wiki/Domain_authority"&gt;domain authority&lt;/a&gt; score. These are likely to be good back links&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Generally, it is painful to deal with bad back links because I&amp;#8217;m not in control. I used a few free backlink checker tools (e.g. &lt;a href="https://search.google.com/search-console/links"&gt;Links report&lt;/a&gt; on Google Search Console, &lt;a href="https://seomator.com/free-backlink-checker-tool"&gt;SEOMATOR&lt;/a&gt;, SEMRush free) and found a lot of spammy sites that I had to request Google to &lt;a href="https://search.google.com/search-console/disavow-links"&gt;disavow&lt;/a&gt;. Otherwise, they may negatively impact the search performance.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Repercussions&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the next few months, my pages are no longer a stop for their redirect. However, web request for those invalid URLs keep coming. The bad pages are still in Google&amp;#8217;s cache. There are a lot of page request with 404 return code, and we consider this an HTTP flood. The problem now is that the amount of 404 return code is impacting how my site ranks in search engine. To make it worse, the amount of these requests with invalid URL increase since August. &lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="289" src="https://www.digihunch.com/wp-content/uploads/2023/11/wp-404.webp" alt="" class="wp-image-12966" srcset="https://www.digihunch.com/wp-content/uploads/2023/11/wp-404.webp 1024w, https://www.digihunch.com/wp-content/uploads/2023/11/wp-404-300x85.webp 300w, https://www.digihunch.com/wp-content/uploads/2023/11/wp-404-768x217.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To fix this, there are two measures. First, in Google search console, I have to tell Google to remove those URLs from its cache. I have identified a number of prefix patterns, and submitted a request for each URL pattern. It takes google a day to have them cleared. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;After that, the bad request will no longer come from Google users clicking on bad URL. In my case, the requests did not reduce significantly, suggesting that most of the requests come from bots. Therefore I had to figure out a way to prevent those bad request hitting my server, which is a typical web application firewall requirement. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Looking for such a solution for my WordPress Security I landed on Cloudflare. Cloudflare is pretty user-friendly with an easy-to-understand &lt;a href="https://developers.cloudflare.com/reference-architecture/cdn-reference-architecture/"&gt;reference architecture&lt;/a&gt;. When I started, Cloudflare can import my DNS records, and guided me to change my name servers so I delegate my DNS management it. When I first move to Cloudflare the website gives &lt;a href="https://developers.cloudflare.com/ssl/troubleshooting/too-many-redirects/"&gt;ERR_TOO_MANY_REDIRECTS&lt;/a&gt;. I ended up having to go to SSL/TLS and set encryption mode to Full (strict) to get rid of this error. I also have to re-configure email forwarding as a result of name server change.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;CloudFlare &lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Even for a self-hosted single-server site, it is very beneficial to place an Application Firewall upfront for WordPress security. I find CloudFlare are very useful service that provides everything else you need to host the web site. For example, it contains a domain registry itself. It manages DNS and allows email forwarding. In addition, it helps generate TLS certificate etc. The free tier covers everything for a small website, with the Application Firewall as the core feature. Within the free tier I can have these features:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;domain registrar and name servers (not for free but at a reasonable cost)&lt;/li&gt;&#10;&lt;li&gt;SSL certificate (not for free but at a reasonable cost)&lt;/li&gt;&#10;&lt;li&gt;Request event tracking&lt;/li&gt;&#10;&lt;li&gt;redirect rule: zone apex to www, and /status to uptime status page&lt;/li&gt;&#10;&lt;li&gt;return code 409 for obsolete URLs (using routes and workers)&lt;/li&gt;&#10;&lt;li&gt;email routing and forwarding&lt;/li&gt;&#10;&lt;li&gt;WAF rules (path, parameter, rate, etc)&lt;/li&gt;&#10;&lt;li&gt;DDoS protection and Bot Fight mode&lt;/li&gt;&#10;&lt;li&gt;hot-linking prevention (i.e. other sites references images on your site directly)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;I am still exploring features for CloudFlare. One stunning feature is routes and workers. Essentially you can serve a function in response to HTTP request at a specific route. This is particularly useful in scenarios where it is not straightforward to add web pages on the backend server. For example, I want requests with certain paths to return HTTP code 490 and do not want to mock with the WordPress server, we can make use of CloudFlare worker.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Lessons Learned&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For WordPress security, never use suspicious plugins. Keep an additional layer of defense in WordPress such as Wordfense. It helps block malicious traffic that went through the first layer. It also helps configure MFA for administrators. &lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://www.digihunch.com/2023/10/the-systems-manager-hodgepodge/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;AWS Systems Manager is an Omnipotent Hodgepodge&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://www.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Workload Identity on Kubernetes 1 of 2 – AKS&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Secure web application deployment</title><link>https://www.digihunch.com/2021/05/secure-web-application-deployment/</link><pubDate>Sun, 16 May 2021 15:19:41 -0400</pubDate><guid>https://www.digihunch.com/2021/05/secure-web-application-deployment/</guid><description>&lt;p class="wp-block-paragraph"&gt;In Nov 2020, I created &lt;a href="https://github.com/digihunch/orthweb/tree/2181001e29b0da5fd55f51a6dc2a522d3f83aee6" class="rank-math-link"&gt;OrthWeb&lt;/a&gt; project, a deployment of Orthanc&amp;#8217;s server. Orthanc is a DICOM viewer and repo shipped in Docker container. In the &lt;a href="https://www.digihunch.com/2020/11/medical-imaging-web-server-deployment-pipeline/" class="rank-math-link"&gt;deployment project&lt;/a&gt;, I use Terraform to provision infrastructure, including a managed PostgreSQL instance, an EC2 instance for docker runtime, and the init script to bring up the web service. I whipped up the project for a demo, and skipped some security configurations. For example, the password was stored in clear text in Terraform configuration. The web certificate is stored in the repository. I recently had some time to fix that. My effort leads up to the conclusion that this requires a better platform (i.e. managed Kubernetes cluster). So I wanted to note down how I got there.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Secret store&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In AWS, both parameter store and secret manager can act as secret store. Secrets manager comes at higher cost but some additional features, such as built-in password generator, secret rotation, and cross-account access. We use Secret Manager but we generate password within Terraform because we need to specify password during database provisioning. Secret store requires certain special characters to be eliminated. Terraform can specify the special characters allowed. For EC2 instance to pull from secret manager, the following entities are needed:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;A secret store&lt;/li&gt;&#10;&lt;li&gt;A VPC endpoint to expose secret store to subnet via private route. &lt;/li&gt;&#10;&lt;li&gt;The VPC endpoint needs its own security group&lt;/li&gt;&#10;&lt;li&gt;The instance profile of the EC2 instance must contain an IAM role to get secret value&lt;/li&gt;&#10;&lt;li&gt;The security group of EC2 instance needs to allow traffic to secret store&lt;/li&gt;&#10;&lt;li&gt;The script from EC2 instance uses VPC endpoint&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;This is a common pattern for interaction between computing object and VPC endpoint. The details are in compute.tf, network.tf, secgrp.tf and secret.tf. The secret name needs to be partially randomized to avoid naming conflict with deactivated secrets.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-large"&gt;&lt;img loading="lazy" decoding="async" width="623" height="323" src="https://www.digihunch.com/wp-content/uploads/2021/05/secmgr.png" alt="" class="wp-image-2250"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Passing Secret to container&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Here is an example CLI command to pull secret:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws secretsmanager get-secret-value --secret-id DatabaseCreds51c1db4172ae9c54 --query SecretString --output text --endpoint-url https://vpce-0897b168cf1c60df2-khx32o7f.secretsmanager.us-east-1.vpce.amazonaws.com | jq -r .password&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The connection is made via private network route (whether the instance is in public or private subnet). Traffic is encrypted in TLS. Once in the operating system, the secret is available as standard output and can be stored to file, or saved in environment variable. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;My first attempted approach is docker&amp;#8217;s secret store and config so that I do not have to store secret in plain text on the file system. I eventually give up this approach due to several hiccups. First, secret and config are part of Docker swarm service. So it requires initializing docker swarm before I could port in the secret, with the following command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ docker swarm init&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ echo mdbuser123 | docker secret create db_un -&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ echo m1p@ssw0rd | docker secret create db_pw -&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ echo 10.2.32.41 | docker config create db_ep -&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The content of the secret and config are presented as files to the container file system at different locations, as can be verified this way:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ docker service create --name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt; --secret&lt;span style="color:#f92672"&gt;=&lt;/span&gt;db_un --secret&lt;span style="color:#f92672"&gt;=&lt;/span&gt;db_pw --config&lt;span style="color:#f92672"&gt;=&lt;/span&gt;db_ep redis:alpine&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ docker container ls&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ docker exec -it c8ed2a278ca8 sh&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# cat /db_ep&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# cat /run/secrets/db_un&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# cat /run/secrets/db_pw&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;This is a great way to pass secret and config to container applications. However, since the values are stored as content of file, the main application must be able to load file content as its own configuration value. In my specific scenario, the application expects explicit value in its &lt;a href="https://orthanc.uclouvain.be/book/users/configuration.html" class="rank-math-link"&gt;configuration file&lt;/a&gt;, or environment variable.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;On the other hand, Docker &lt;a href="https://techbeacon.com/devops/how-keep-your-container-secrets-secure" class="rank-math-link"&gt;document&lt;/a&gt; states that docker secrets do not set environment variables directly. this was a conscous decision, because env var can unintentionally be leaked between containers. In other word I could present secrets as files but the application cannot use it. There is potentially a workaround &lt;a href="https://medium.com/@adrian.gheorghe.dev/using-docker-secrets-in-your-environment-variables-7a0609659aab" class="rank-math-link"&gt;here&lt;/a&gt; which is great function wise but an additional layer of complexity.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Moreover, I later discovered that this isn&amp;#8217;t even a viable approach if I use docker compose. This is because I must declare those entries from secret store or config store as &lt;a href="https://docs.docker.com/compose/compose-file/compose-file-v3/#configs" class="rank-math-link"&gt;external&lt;/a&gt;, and external secrets are not even available to containers created by docker-compose. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With reluctance, I store the config and secret keys and values to a file, and use the &lt;a href="https://docs.docker.com/compose/environment-variables/#the-env-file" class="rank-math-link"&gt;env_file&lt;/a&gt; section in docker compose to import them as environment variables. The application can pick up environment variables as configuration values.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;X509 Certificate&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We use a self-signed X509 certificate, along with the private key. The &lt;a href="https://orthanc.uclouvain.be/book/faq/https.html#securing-orthanc-using-self-signed-certificate" class="rank-math-link"&gt;creation&lt;/a&gt; is straightforward. However, when I tested on Mac, the browser does not load the page for &lt;a href="https://support.apple.com/en-us/HT210176" class="rank-math-link"&gt;this&lt;/a&gt; reason. Since macOS 10.15, the certificate requires several extensions: ExtendedKeyUsage, Subject alternative names and DNS name. The native openssl from the operating system is outdated (v 1.0.2) and I had to install openssl11 package and create it as follows:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;openssl11 req -x509 -nodes -days &lt;span style="color:#ae81ff"&gt;365&lt;/span&gt; -newkey rsa:2048 -keyout /tmp/private.key -out /tmp/certificate.crt -subj /C&lt;span style="color:#f92672"&gt;=&lt;/span&gt;CA/ST&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Ontario/L&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Waterloo/O&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Digihunch/OU&lt;span style="color:#f92672"&gt;=&lt;/span&gt;Imaging/CN&lt;span style="color:#f92672"&gt;=&lt;/span&gt;digihunch.com/emailAddress&lt;span style="color:#f92672"&gt;=&lt;/span&gt;info@3.237.97.93 -addext extendedKeyUsage&lt;span style="color:#f92672"&gt;=&lt;/span&gt;serverAuth -addext subjectAltName&lt;span style="color:#f92672"&gt;=&lt;/span&gt;DNS:orthweb.digihunch.com,DNS:digihunch.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The Mac uses libreSSL backed openSSL utility and can achieve the same with slightly different command line argument.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Next Step&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The limitation with passing secret concerns me and I&amp;#8217;m looking to move to managed Kubernetes platform where &lt;a href="https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables" class="rank-math-link"&gt;secrets&lt;/a&gt; can be ported to environment variable of Pods. We can also consider &lt;a href="https://docs.aws.amazon.com/AmazonECS/latest/developerguide/specifying-sensitive-data.html" class="rank-math-link"&gt;ECS&lt;/a&gt; in AWS which allows to inject sensitive data from secret manager to container. &lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://www.digihunch.com/2021/04/preparing-certified-kubernetes-administrator-exam/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Certified Kubernetes Administrator (CKA) Exam&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://www.digihunch.com/2021/05/getting-started-with-github-actions/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Getting started with GitHub Actions&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Cryptography basics 2 of 2</title><link>https://www.digihunch.com/2019/09/cryptographic-concepts-for-busy-it-professionals-2-of-2/</link><pubDate>Sun, 08 Sep 2019 21:21:41 -0400</pubDate><guid>https://www.digihunch.com/2019/09/cryptographic-concepts-for-busy-it-professionals-2-of-2/</guid><description>&lt;p class="wp-block-paragraph"&gt;My previous &lt;a href="https://www.digihunch.com/2019/07/practical-cryptography-for-it-professional/"&gt;post&lt;/a&gt; outlines several core concepts around cryptography, such as asymmetric key encryption, digital certificate, the encoding formats and relevant file extensions. In this article, we continue to explore cryptography use cases, where these concepts are connected and put into application.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The most important use case is TLS handshake. I cannot stress enough how paramount this scenario is. This use case and its variation can be found in almost every situation where connection needs to be secured.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;TLS handshake&lt;/strong&gt;: the process in which client and server establish secure connection. During the handshake, two parties agree on TLS version, decide on cipher suite, authenticate the identity of each other (although client identity authentication is less common), and generate session key for symmetric encryption after the handshake. Details steps are very important. &lt;a href="https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_7.1.0/com.ibm.mq.doc/sy10660_.htm"&gt;Here&lt;/a&gt; is a fairly thorough reference, and here is a great diagram:&lt;/p&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img loading="lazy" decoding="async" width="1496" height="792" src="https://www.digihunch.com/wp-content/uploads/2019/10/TLS.png" alt="" class="wp-image-152"/&gt;&lt;figcaption class="wp-element-caption"&gt;TLS handshake&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Secure browser connection&lt;/strong&gt;: The most widespread use of TLS handshake is to secure browser connection with HTTPS:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;Browser initiates connection to the server;&lt;/li&gt;&#10;&lt;li&gt;Server sends browser its certificate (public key + digital signature signed by CA);&lt;/li&gt;&#10;&lt;li&gt;Browser has preloaded public key of CA and uses it to decrypt digital signature and get the digest of public key;&amp;nbsp;&lt;/li&gt;&#10;&lt;li&gt;Browser calculate digest of received public key and compares it against the digest from the previous step;&lt;/li&gt;&#10;&lt;li&gt;If the result is the same, public key is trusted, a green lock is displayed; otherwise, a warning is displayed;&lt;/li&gt;&#10;&lt;li&gt;proceed to the rest of the steps in TLS handshake.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Secure connection in Java&lt;/strong&gt;: Java applications manages keys and certificates through two classes: java.security.KeyStore and java.security.TrustStore. Suppose a Java application client initiates TLS connection to server. The server application will present its certificates from server&amp;#8217;s Key Store. The client will use certificates stored in client&amp;#8217;s Trust Store to verify the identity of the server. Once validated, the client then presents certificates stored in client&amp;#8217;s Key Store back to the server for validation.&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;A KeyStore keeps keys and certificates for your own application. Typically, you store a KeyPair in a KeyStore file.&lt;/li&gt;&#10;&lt;li&gt;A TrustStore keeps the certificates of external systems that your application trusts.&amp;nbsp;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Below is a great diagram:&lt;/p&gt;&#10;&lt;figure class="wp-block-image"&gt;&lt;img loading="lazy" decoding="async" width="1362" height="956" src="https://www.digihunch.com/wp-content/uploads/2019/10/JavaJKS.png" alt="" class="wp-image-153"/&gt;&lt;figcaption class="wp-element-caption"&gt;Secure Java application in TLS&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;JKS file &lt;/strong&gt;is Java&amp;#8217;s version of PKCS#12 (private key + certificate, password protected). Entries in a JKS file must have an &amp;#8220;alias&amp;#8221; that is unique. The JKS file type can be used for both Key Store and Trust Store. When it&amp;#8217;s used in Key Store, it contains a certificate and private key for the Java application. When it&amp;#8217;s used in Trust Store, it only contains certificate from external trusted applications. Note that JKS is the default keystore format until Java 8. Since Java 9 the default keystore format is PKCS12.&amp;nbsp;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Finally, we can introduce some tools:&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Command line Tools&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;openssl &lt;/strong&gt;is a versatile tool for cryptography and keytool is a similar tool for Java applications.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;keytool &lt;/strong&gt;is for store keys/certificates in Java Key Store or Trust Store.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;I do not include any openssl or keytool command in this article in order to remain theoretical. However, once through the conceptual hurdles, one should become fairly comfortable picking up the tools and understand why each command is needed to achieve its purpose.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://www.digihunch.com/2019/08/aws-certified-devops-engineer-exam-tips/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;AWS Certified DevOps Engineer Exam Tips&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://www.digihunch.com/2019/10/personal-vim-cheatsheet/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Personal Vim cheatsheet&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>