<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Yahe&#39;s Space</title>
  <subtitle></subtitle>
  <link href="https://yahes.space/feed.xml" rel="self"/>
  <link href="https://yahes.space/"/>
  
    <updated>2021-12-29T00:00:00+00:00</updated>
  
  <id>https://yahes.space</id>
  <author>
    <name>yahsieh</name>
    <email>yunganh@uci.edu</email>
  </author>
  
    
    <entry>
      <title>Using Yubikey with PAM module</title>
      <link href="https://yahes.space/posts/using-yubikey-with-pam-module/"/>
      <updated>2021-10-08T00:00:00+00:00</updated>
      <id>https://yahes.space/posts/using-yubikey-with-pam-module/</id>
      <content type="html">
        <![CDATA[
      <p>I just recently bought a YubiKey 5 NFC as my first USB security token.
This security key can verify accounts without passwords or act as proof of user presence. I'm using my YubiKey to password-less unlock 1password and two-factor authentication (2FA) laptop login. 2FA is authenticating with another method other than you used as the first factor, commonly as password. This provides extra security if your password is leaked, breached, or guessed by a hacker[^1].</p>
<h3>Universal 2nd Factor (U2F)</h3>
<blockquote>
<p>Universal 2nd Factor (U2F) is an open standard that strengthens and simplifies two-factor authentication (2FA) using specialized USB or NFC devices based on similar security technology found in smart cards.
While initially developed by Google and Yubico, with contribution from NXP Semiconductors, the standard is now hosted by the FIDO Alliance.
-- from <a href="https://wiki.archlinux.org/title/Universal_2nd_Factor#Authentication_for_Arch_Linux">arch wiki</a></p>
</blockquote>
<p>YubiKey team developed pam_u2f module, also open source at GitHub <a href="https://github.com/Yubico/pam-u2f">Yubico/pam-u2f</a>. With pam_u2f, we can easily configure authenticating methods for Linux. Although YubiKey does way more than U2F authenticating (OTP, OpenPGP, ...), this post will only focus on U2F.</p>
<p>Install it on ArchLinux:</p>
<pre><code>pacman -S pam_u2f
</code></pre>
<p>Generate a key for user</p>
<pre><code>mkdir ~/.config/Yubico
pamu2fcfg -o pam://hostname -i pam://hostname &gt; ~/.config/Yubico/u2f_keys
</code></pre>
<p><strong>pam_u2f</strong> looks for key file at <code>$XDG_CONFIG_HOME/Yubico/u2f_keys</code>. If <code>$XDG_CONFIG_HOME</code> is not set, <code>$HOME/.config/Yubico/u2f_keys</code> is used.</p>
<h3>Important</h3>
<p>Before configuring PAM rules, be sure to back up the current setting and leave a console with edit privilege for PAM files. You may get locked out (since it's too secure) during the process. If this happens, plug your storage device into another computer and fix it.
Keep in mind that the order of the auth rules in PAM config matters.</p>
<h3>Passwordless Authentication</h3>
<p>Here's how to passwordless sudo:</p>
<p>Open <code>/etc/pam.d/sudo</code> and add</p>
<pre><code>auth    sufficient    pam_u2f.so cue origin=pam://hostname appid=pam://hostname
</code></pre>
<p>before any <code>auth required</code> or <code>auth include</code></p>
<p>Passwordless unlock 1password by adding the same line to <code>/etc/pam.d/polkit-1</code></p>
<h3>2nd Factor Authentication</h3>
<p>2FA log in to gnome desktop:</p>
<p>Open <code>/etc/pam.d/gdm-password</code> and add</p>
<pre><code>auth    required        pam_u2f.so cue nouserok origin=pam://hostname appid=pam://hostname
</code></pre>
<p>after auth lines. <code>nouserok</code> flag is for user that don't have a security key (or can't find u2f_keys in certain path)</p>
<h3>OpenSSH 8.2</h3>
<blockquote>
<p>OpenSSH supports FIDO/U2F hardware tokens natively since 8.2. Both the client and server must support the ecdsa-sk/ed25519-sk key types. Generate a security key backed key pair with:</p>
<ul>
<li>for ECDSA key
<code>ssh-keygen -t ecdsa-sk</code></li>
<li>for Ed25519 key
<code>ssh-keygen -t ed25519-sk</code></li>
</ul>
<p>-- from <a href="https://wiki.archlinux.org/title/Universal_2nd_Factor#OpenSSH">arch wiki</a></p>
</blockquote>
<p>After generating keys, copy the public key to <code>~/.ssh/authorized_keys</code> at destination server.
Do notice that ssh does not prompt for tapping the security key.</p>
<h3>SELinux</h3>
<p>Some distribution that uses SELinux may encounter trouble when accessing credential files. 2FA will be denied or may be bypassed if nouserok flag is set.</p>
<p>Check out details at <a href="https://access.redhat.com/security/cve/CVE-2020-24612">https://access.redhat.com/security/cve/CVE-2020-24612</a></p>
<h2>More Products</h2>
<h3>YubiKey Bio</h3>
<p>Unfortunately, they rolled out the new YubiKey Bio series a week after I bought this one. I'm guessing the YubiKey Bio will work with the authentication method mentioned above as the current module contains <code>userverification</code> flag. If this doesn't work, I tested with <code>pinverification=1</code> and the user interface prompted to input PIN code correctly. However, it would be disappointing if fingerprint verification doesn't work since we can achieve the same level of security with pin verification and a &quot;normal&quot; YubiKey.</p>
<p>A drawback of using YubiKey Bio is it does not provide NFC function, which I guess is understandable because of power and stuff (or maybe they could provide one in the future?). Thus we cannot use it with various mobile devices not compatible with USB-A/USB-C. This drawback is negligible since I only use it with laptop/PC now. Waiting for more details from <a href="https://www.brighttalk.com/webcast/15793/507115">webinar</a> at 10 a.m. PT on Mon. Oct. 18</p>
<p>Might buy one if this gets a discount at Black Friday Sale.</p>
<h3>Google Titan</h3>
<p>I don't have one.</p>
<h3>Solo Key</h3>
<p>Solo key is an open source implementation of security key with FIDO standard. It should work fine with U2F PAM module. Much cheaper than Google Titan and YubiKeys.</p>
<p>[^1]: Recent Twitch incident (<a href="https://blog.twitch.tv/en/2021/10/06/updates-on-the-twitch-security-incident/">https://blog.twitch.tv/en/2021/10/06/updates-on-the-twitch-security-incident/</a>)</p>

    ]]>
      </content>
    </entry>
  
    
    <entry>
      <title>Deploying ELK stack on Kubernetes</title>
      <link href="https://yahes.space/posts/deploying-elk-stack-on-kubernetes/"/>
      <updated>2021-12-29T00:00:00+00:00</updated>
      <id>https://yahes.space/posts/deploying-elk-stack-on-kubernetes/</id>
      <content type="html">
        <![CDATA[
      <p>So, DigitalOcean announced an event called <a href="https://www.digitalocean.com/community/pages/kubernetes-challenge">DigitalOcean Kubernetes Challenge</a>, which gives me the opportunity to learn Kubernetes skills before the end of the year.</p>
<p>Though with experience in docker and docker-compose, I’m totally new to kubernetes. My impression of k8s is a bunch of yaml files. In this post, I followed this <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-an-elasticsearch-fluentd-and-kibana-efk-logging-stack-on-kubernetes">tutorial</a>, but I did a little twist to deploy ELK stack so that I could learn to debug k8s problems instead of simply doing copy pastas.</p>
<h3>Kubernetes Cluster</h3>
<p>First we need to create a Kubernetes cluster, go to the dashboard and create a k8s cluster with 3 nodes. After the cluster is created, generate an API token for connecting to the cluster using <code>doctl</code>.</p>
<pre class="language-bash"><code class="language-bash"><span class="token comment"># download and extract doctl bin</span><br><span class="token function">wget</span> https://github.com/digitalocean/doctl/releases/download/v1.66.0/doctl-1.66.0-linux-amd64.tar.gz<br><span class="token function">tar</span> xf doctl-1.66.0-linux-amd64.tar.gz<br><span class="token function">mv</span> doctl /usr/local/bin<br><span class="token comment"># authenticate</span><br>doctl auth init    <span class="token comment"># paste the api token here</span><br>doctl account get  <span class="token comment"># verify the api token</span><br><span class="token comment"># get k8s config file</span><br>doctl kubernetes cluster kubeconfig save k8s-first-proj</code></pre>
<p>Next step, install <code>kubectl</code> to control the Kubernetes cluster manager. To install kubectl on ArchLinux, simply do <code>pacman -S kubectl</code>.</p>
<h3>Elasticsearch</h3>
<p>This part consist of a Statefulset and a service. K8s Statefulset is for storing persistent volumes. Normally, data are lost after we shut a container down. So using persistent volumes ensure stored contents would not be discarded after container’s lifetime ended. In this YAML file, be sure not to remove the <code>increase-vm-max-map</code> section. This section ensure the <code>mmapfs</code> directory large enough that Elasticsearch requires. Also, the <code>resource.limits</code> section defines this service can use minimum 0.1 vCPU to maximum 1 vCPU.</p>
<p>K8s service is for exporting ports from the Statefulset. Here we export port <code>9200</code> for Kibana and Logstash.</p>
<pre class="language-bash"><code class="language-bash"><span class="token comment"># deploy the statefulset</span><br>kubectl create -f elasticsearch_statefulset.yaml<br><span class="token comment"># check the progress of deployment</span><br>kubectl rollout status sts/es-cluster<br>kubectl get pods -n kube-logging    <span class="token comment"># this should show 3 pods running (es-cluster-{0,1,2})</span><br><span class="token comment"># deploy the service</span><br>kubectl create -f elasticsearch_svc.yaml</code></pre>
<h3>Kibana</h3>
<p>In this part, we define a deployment template with kibana service connected to ES, and export 5601 port for user interface. To interact with the UI, we need to port-forward 5601 to localhost, then open browser with URL: <code>http://localhost:5601</code></p>
<pre class="language-bash"><code class="language-bash"><span class="token comment"># deploy</span><br>kubectl create -f kibana.yaml<br><span class="token comment"># port-forwarding to localhost</span><br>kubectl port-forward svc/kibana <span class="token number">5601</span>:5601 --namespace<span class="token operator">=</span>kube-logging</code></pre>
<h3>Logstash</h3>
<p>This part consist of a deployment template and a configmap and a service. The configmap here is for modifying input and output config.</p>
<p>In our setup, Logstash get messages from Filebeat and forward them to Elasticsearch. Logs that passed into logstash get into input-filter-output pipeline. In input section, we collect logs from <code>beats</code> with port <code>5044</code>. In output section, set the Elasticsearch endpoint with <code>http://elasticsearch:9200</code></p>
<pre class="language-bash"><code class="language-bash"><span class="token comment"># deploy</span><br>kubectl create -f logstash.yaml<br><span class="token comment"># check</span><br>kubectl rollout status deployment/logstash -n kube-logging</code></pre>
<h3>Filebeat</h3>
<p>In this part, we define a DaemonSet, which will be deployed on every node for collecting logs. For discovering logs in pods, we also need to define and assign a ServiceAccount with several permissions.</p>
<pre class="language-bash"><code class="language-bash"><span class="token comment"># deploy</span><br>kubectl create -f filebeat.yaml<br>kubectl rollout status ds/filebeat -n kube-logging</code></pre>
<p>This part gave me a headache. I followed every tutorials I could find and nothing really works. I turned on every debug flag and tried to figure out what’s happening. After that, I determined that everything other than Filebeat works. Then, I found that there are no logs in <code>/var/lib/docker/containers</code>. I came across this <a href="https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter/issues/105">GitHub Issue</a> and followed the solution and boom! Everything is running! So I guess if we get stuck on a problem, we have to RTFM before doing anything stupid.</p>
<p>There are some commands that I found useful when I debug this problem:</p>
<p>Check logs: <code>kubectl logs ds/filebeat -n kube-logging</code></p>
<p>Run commands in pod: <code>kubectl exec (POD | TYPE/NAME) -t -- [COMMAND]</code>, like <code>kubectl exec -n kube-logging ds/filebeat -t ls /var/log</code></p>
<p>Show details: <code>kubectl describe ds filebeat -n kube-logging</code></p>

    ]]>
      </content>
    </entry>
  
</feed>