<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ exam  - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ exam  - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Tue, 23 Jun 2026 22:45:29 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/exam/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Pass the Certified Kubernetes Security Specialist Exam – Cheat sheet and Study Guide ]]>
                </title>
                <description>
                    <![CDATA[ By Faizan Bashir This article is based on my experience studying for and passing the Certified Kubernetes Security Specialist exam. I passed the exam on my first attempt in Sep 2021. I passed the Certified Kubernetes Application Developer exam back i... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-pass-the-certified-kubernetes-security-specialist-exam/</link>
                <guid isPermaLink="false">66d45ef4680e33282da25e6f</guid>
                
                    <category>
                        <![CDATA[ cheatsheet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ exam  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Kubernetes ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Tue, 08 Mar 2022 17:40:39 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/03/cks.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Faizan Bashir</p>
<p>This article is based on my experience studying for and passing the Certified Kubernetes Security Specialist exam. I passed the exam on my first attempt in Sep 2021.</p>
<p>I passed the Certified Kubernetes Application Developer exam back in Feb 2020, followed by Certified Kubernetes Administrator in March 2020. </p>
<p>The Certified Kubernetes Security Specialist or CKS exam was released around November, 2020, but I didn't have a chance to take that exam before Sep 2021.</p>
<p>As a bit of background information, I have been working with Kubernetes for the past 3 years almost on a day-to-day basis and that experience was an added advantage in helping me pass the CKS.</p>
<p>In this article, I'll share some resources that should help you study for and pass the exam, along with a helpful cheatsheet you can use while preparing. I'll also share some advice that should help you along the way.</p>
<h3 id="heading-what-is-kubernetes">What is Kubernetes?</h3>
<p>Kubernetes is the most evolved and feature-rich Container Orchestration system out there, and it keeps getting better. </p>
<p>It has an enormous community to support, and it's always building new features and resolving issues. Kubernetes is certainly evolving at a breakneck pace, and it becomes a challenge to keep up with its pace of development. This makes it the best bet for a container orchestration solution.</p>
<hr>
<h2 id="heading-table-of-contents">Table of Contents:</h2>
<ul>
<li><a class="post-section-overview" href="#heading-resources-for-the-exam">Resources for the CKS Exam</a></li>
<li><a class="post-section-overview" href="#heading-aliases">Aliases</a><ul>
<li><a class="post-section-overview" href="#heading-vi-defaults-for-vimrc">vi defaults for ~/.vimrc</a></li>
<li><a class="post-section-overview" href="#heading-kubectl-defaults-for-bashrc">kubectl defaults for ~/.bashrc</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-shortcuts">Shortcuts</a></li>
<li><a class="post-section-overview" href="#heading-kubernetes-cheat-sheet">Kubernetes Cheat Sheet</a><ul>
<li><a class="post-section-overview" href="#heading-kubectl-run-command">kubectl run command</a></li>
<li><a class="post-section-overview" href="#heading-how-to-generate-yaml-spec-from-an-existing-pod">How to generate yaml spec from an existing pod</a></li>
<li><a class="post-section-overview" href="#heading-kubectl-pod-commands">kubectl pod commands</a></li>
<li><a class="post-section-overview" href="#heading-how-to-print-logs-and-export-them">How to print logs and export them</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-config-maps-and-secrets">How to create configmaps and secrets</a></li>
<li><a class="post-section-overview" href="#heading-helpful-commands-for-debugging">Helpful commands for debugging</a></li>
<li><a class="post-section-overview" href="#heading-rolling-updates-and-rollouts">Rolling updates and rollouts</a></li>
<li><a class="post-section-overview" href="#heading-scale-and-autoscale-command">Scale and autoscale command</a></li>
<li><a class="post-section-overview" href="#heading-network-policy">Network policy</a></li>
<li><a class="post-section-overview" href="#heading-static-analysis-using-kubesec">Static analysis using Kubesec</a></li>
<li><a class="post-section-overview" href="#heading-vulnerability-scanning-using-trivvy">Vulnerability scanning using Trivvy</a></li>
<li><a class="post-section-overview" href="#heading-how-to-remove-unwanted-services">How to remove unwanted services</a></li>
<li><a class="post-section-overview" href="#heading-runtime-classes">Runtime classes</a></li>
<li><a class="post-section-overview" href="#heading-rbac-commands">RBAC commands</a></li>
<li><a class="post-section-overview" href="#heading-cluster-maintenance">Cluster maintenance</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-cks-exam-tips">CKS Exam Tips</a><ul>
<li><a class="post-section-overview" href="#heading-json-and-jsonpath">JSON and JSONPath</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-cks-exam-topics">CKS Exam Topics</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-secure-and-harden-container-images">How to secure and harden container images</a></li>
<li><a class="post-section-overview" href="#heading-how-to-minimise-os-footprint">How to minimise OS footprint</a><ul>
<li><a class="post-section-overview" href="#heading-conatiner-layers">Conatiner layers</a></li>
<li><a class="post-section-overview" href="#heading-multi-stage-builds">Multi stage builds</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-limit-node-access">How to limit node access</a></li>
<li><a class="post-section-overview" href="#heading-ssh-hardening">SSH hardening</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-disable-ssh">How to disable SSH</a></li>
<li><a class="post-section-overview" href="#heading-how-to-remove-obsolete-packages-and-services">How to remove obsolete packages and services</a></li>
<li><a class="post-section-overview" href="#heading-how-to-restrict-kernel-modules">How to restrict kernel modules</a></li>
<li><a class="post-section-overview" href="#heading-how-to-identify-and-disable-open-ports">How to identify and disable open ports</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-restrict-network-access">How to restrict network access</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-identity-a-service-running-on-port">How to identity a service running on port</a></li>
<li><a class="post-section-overview" href="#heading-ufw-firewall">UFW firewall</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-linux-syscalls">Linux syscalls</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-trace-syscalls-using-strace">How to trace Syscalls using Strace</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-aquasec-tracee">AquaSec tracee</a></li>
<li><a class="post-section-overview" href="#heading-how-to-restrict-syscalls-with-seccomp">How to restrict syscalls with Seccomp</a><ul>
<li><a class="post-section-overview" href="#heading-seccomp-in-kubernetes">Seccomp in Kubernetes</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-apparmor">AppArmor</a><ul>
<li><a class="post-section-overview" href="#heading-how-to-use-apparmor-in-kubernetes">How to use AppArmor in Kubernetes</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-linux-capabilities">Linux capabilities</a></li>
</ul>
</li>
<li><a class="post-section-overview" href="#heading-how-to-prepare-for-the-exam">How to Prepare for the Exam</a></li>
<li><a class="post-section-overview" href="#heading-practice-practice-and-practice">Practice, practice, and practice!</a></li>
</ul>
<hr>
<h2 id="heading-resources-for-the-exam">Resources for the Exam</h2>
<p>The following are a few awesome resources available on passing the CKS exam:</p>
<ol>
<li><a target="_blank" href="https://www.udemy.com/course/certified-kubernetes-security-specialist/">Certified Kubernetes Security Specialist by Killer.sh</a> </li>
<li><a target="_blank" href="https://kodekloud.com/courses/certified-kubernetes-security-specialist-cks/">Certified Kubernetes Security Specialist (CKS) by KodeKloud</a></li>
<li><a target="_blank" href="https://github.com/walidshaari/Certified-Kubernetes-Security-Specialist">Walid Shaari has gathered some indispensable materials for the CKS exam</a></li>
<li><a target="_blank" href="https://github.com/abdennour/certified-kubernetes-security-specialist">Abdennour's References for CKS Exam Objectives</a></li>
<li><a target="_blank" href="https://github.com/ibrahimjelliti/CKSS-Certified-Kubernetes-Security-Specialist">Ibrahim Jelliti's collection of resources to prepare for the Certified Kubernetes Security Specialist (CKSS) exam</a></li>
</ol>
<p>The courses for KodeKloud and Killer.sh provide mock exam simulators which are very helpful in preparing for the exam, and provide a pretty good idea of what the exam looks like. I strongly suggest enrolling in one or both courses. </p>
<p>Purchasing the exam from the Linux Foundation gives you 2 free attempts at the exam simulator from killer.sh. That way if you are well-versed with the contents of the curriculum you can skip the courses and directly go for the exam simulator provided with the exam.</p>
<p>The exam costs $375 but there are offers and deals available, and if you look for them you might be able to get a better price. The duration of the exam is 2 hours and is valid for 2 years, unlike the CKA and CKAD which are valid for 3 years.</p>
<h2 id="heading-aliases">Aliases</h2>
<p>The CKS is a performance-based exam where you are provided with an exam simulator in which you have to work out the problems. You are allowed to open only one tab apart from the exam tab. </p>
<p>Since this exam requires you to write a lot of commands, I figured early on that I'd have to rely on aliases to reduce the number of keystrokes to save time.</p>
<p>I used the <strong>vi</strong> editor during the exam, so here I will share some useful tips for this editor.</p>
<h3 id="heading-vi-defaults-for-vimrc">vi defaults for ~/.vimrc:</h3>
<pre><code>vi ~/.vimrc
---
:set number
:set et
:set sw=<span class="hljs-number">2</span> ts=<span class="hljs-number">2</span> sts=<span class="hljs-number">2</span>
---
^: Start <span class="hljs-keyword">of</span> word <span class="hljs-keyword">in</span> line
<span class="hljs-number">0</span>: Start <span class="hljs-keyword">of</span> line
<span class="hljs-attr">$</span>: End <span class="hljs-keyword">of</span> line
<span class="hljs-attr">w</span>: End <span class="hljs-keyword">of</span> word
<span class="hljs-attr">GG</span>: End <span class="hljs-keyword">of</span> file
</code></pre><h3 id="heading-kubectl-defaults-for-bashrc">kubectl defaults for ~/.bashrc:</h3>
<pre><code>vi ~/.bashrc
---
alias k=<span class="hljs-string">'kubectl'</span>
alias kg=<span class="hljs-string">'k get'</span>
alias kd=<span class="hljs-string">'k describe'</span>
alias kl=<span class="hljs-string">'k logs'</span>
alias ke=<span class="hljs-string">'k explain'</span>
alias kr=<span class="hljs-string">'k replace'</span>
alias kc=<span class="hljs-string">'k create'</span>
alias kgp=<span class="hljs-string">'k get po'</span>
alias kgn=<span class="hljs-string">'k get no'</span>
alias kge=<span class="hljs-string">'k get ev'</span>
alias kex=<span class="hljs-string">'k exec -it'</span>
alias kgc=<span class="hljs-string">'k config get-contexts'</span>
alias ksn=<span class="hljs-string">'k config set-context --current --namespace'</span>
alias kuc=<span class="hljs-string">'k config use-context'</span>
alias krun=<span class="hljs-string">'k run'</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">do</span>=<span class="hljs-string">'--dry-run=client -oyaml'</span>
<span class="hljs-keyword">export</span> force=<span class="hljs-string">'--grace-period=0 --force'</span>

source &lt;(kubectl completion bash)
source &lt;(kubectl completion bash | sed <span class="hljs-string">'s/kubectl/k/g'</span> )
complete -F __start_kubectl k


alias krp=<span class="hljs-string">'k run test --image=busybox --restart=Never'</span>
alias kuc=<span class="hljs-string">'k config use-context'</span>
---
</code></pre><h2 id="heading-shortcuts">Shortcuts</h2>
<p>The <code>kubectl get</code> command provides short catchy names for accessing resources and like <code>pvc</code> for <code>persistentstorageclaim</code>. These can help save a lot of keystrokes and valuable time during the exam.</p>
<ul>
<li><strong>po</strong> for <code>pods</code></li>
<li><strong>rs</strong> for <code>replicasets</code></li>
<li><strong>deploy</strong> for <code>deployments</code></li>
<li><strong>svc</strong> for <code>services</code></li>
<li><strong>ns</strong> for <code>namespace</code></li>
<li><strong>netpol</strong> for <code>networkpolicy</code></li>
<li><strong>pv</strong> for <code>persistentstorage</code></li>
<li><strong>pvc</strong> for <code>persistentstorageclaim</code></li>
<li><strong>sa</strong> for <code>serviceaccounts</code></li>
</ul>
<h2 id="heading-kubernetes-cheat-sheet">Kubernetes Cheat Sheet</h2>
<h3 id="heading-kubectl-run-command">kubectl run command</h3>
<p>The <code>kubectl run</code> command provides a flag <code>--restart</code> which allows you to create different kinds of Kubernetes objects from a Deployment to CronJob. </p>
<p>The below snippet shows the different options available for the <code>--restart</code> flag.</p>
<pre><code>k run:
--restart=Always                             #Creates a deployment
--restart=Never                              #Creates a Pod
--restart=OnFailure                          #Creates a Job
--restart=OnFailure --schedule=<span class="hljs-string">"*/1 * * * *"</span> #Creates a CronJob
</code></pre><h3 id="heading-how-to-generate-yaml-spec-from-an-existing-pod">How to generate yaml spec from an existing pod</h3>
<p>Sometimes it's easier to generate a spec from an existing pod and make changes to it than to create a new one from scratch. The <code>kubectl get pod</code> command provides us with the required flags to output the pod spec in the format we want.</p>
<pre><code>kgp &lt;pod-name&gt; -o wide

# Generating YAML Pod spec
kgp &lt;pod-name&gt; -o yaml
kgp &lt;pod-name&gt; -o yaml &gt; &lt;pod-name&gt;.yaml

# Get a pod's YAML spec without cluster specific information
kgp my-pod -o yaml --export &gt; &lt;pod-name&gt;.yaml
</code></pre><h3 id="heading-kubectl-pod-commands">kubectl pod commands</h3>
<p>The <code>kubectl run</code> command provides a lot of options, like specifying requests and the limits a pod is supposed to use or the commands a container should run once created.</p>
<pre><code># Output YAML <span class="hljs-keyword">for</span> a nginx pod running an echo command
krun nginx --image=nginx --restart=Never --dry-run -o yaml -- <span class="hljs-regexp">/bin/</span>sh -c <span class="hljs-string">'echo Hello World!'</span>
# Output YAML <span class="hljs-keyword">for</span> a busybox pod running a sleep command
krun busybox --image=busybox:<span class="hljs-number">1.28</span> --restart=Never --dry-run -o yaml -- <span class="hljs-regexp">/bin/</span>sh -c <span class="hljs-string">'while true; do echo sleep; sleep 10; done'</span>
# Run a pod <span class="hljs-keyword">with</span> set requests and limits
krun nginx --image=nginx --restart=Never --requests=<span class="hljs-string">'cpu=100m,memory=512Mi'</span> --limits=<span class="hljs-string">'cpu=300m,memory=1Gi'</span>
# Delete pod without delay
k <span class="hljs-keyword">delete</span> po busybox --grace-period=<span class="hljs-number">0</span> --force
</code></pre><h3 id="heading-how-to-print-logs-and-export-them">How to print logs and export them</h3>
<p>Logs are the fundamental source of information when it comes to debugging an application. The <code>kubectl logs</code> command provides the functionality to check the logs of a given pod. You can use the below commands to check the logs of a given pod.</p>
<pre><code>kubectl logs deploy/&lt;podname&gt;
kubectl logs deployment/&lt;podname&gt;
#Follow logs
kubectl logs deploy/&lt;podname&gt; --tail 1 --follow
</code></pre><p>Apart from just looking at logs, we can also export logs to a file for further debugging of sharing the same with anyone.</p>
<pre><code>kubectl logs &lt;podname&gt; --namespace &lt;ns&gt; &gt; <span class="hljs-regexp">/path/</span>to/file.format
</code></pre><h3 id="heading-how-to-create-config-maps-and-secrets">How to create config maps and secrets</h3>
<p>The <code>kubectl create</code> command lets us create ConfigMaps and Secrets from the command line. We can also use the YAML file to create the same resources and by using <code>kubectl apply -f &lt;filename&gt;</code> we can apply the commands.</p>
<pre><code>kc cm my-cm --<span class="hljs-keyword">from</span>-literal=APP_ENV=dev
kc cm my-cm --<span class="hljs-keyword">from</span>-file=test.txt
kc cm my-cm --<span class="hljs-keyword">from</span>-env-file=config.env

kc secret generic my-secret --<span class="hljs-keyword">from</span>-literal=APP_SECRET=sdcdcsdcsdcsdc
kc secret generic my-secret --<span class="hljs-keyword">from</span>-file=secret.txt
kc secret generic my-secret --<span class="hljs-keyword">from</span>-env-file=secret.env
</code></pre><h3 id="heading-helpful-commands-for-debugging">Helpful commands for debugging</h3>
<p>Debugging is a very important skill when you're facing issues and errors both in our day jobs and while solving problems in the CKS exam. </p>
<p>Apart from the ability to output logs from a container, the <code>kubectl exec</code> commands lets you log in to a running container and debug issues. While inside the container you can also use utilities like <code>nc</code> and <code>nslookup</code> to diagnose networking-related issues.</p>
<pre><code># Run busybox container
k run busybox --image=busybox:<span class="hljs-number">1.28</span> --rm --restart=Never -it sh
# Connect to a specific container <span class="hljs-keyword">in</span> a Pod
k exec -it busybox -c busybox2 -- <span class="hljs-regexp">/bin/</span>sh
# adding limits and requests <span class="hljs-keyword">in</span> command
kubectl run nginx --image=nginx --restart=Never --requests=<span class="hljs-string">'cpu=100m,memory=256Mi'</span> --limits=<span class="hljs-string">'cpu=200m,memory=512Mi'</span>
# Create a Pod <span class="hljs-keyword">with</span> a service
kubectl run nginx --image=nginx --restart=Never --port=<span class="hljs-number">80</span> --expose
# Check port
nc -z -v -w <span class="hljs-number">2</span> &lt;service-name&gt; &lt;port-name&gt;
# NSLookup
nslookup &lt;service-name&gt;
nslookup 10-32-0-10.default.pod
</code></pre><h3 id="heading-rolling-updates-and-rollouts">Rolling updates and rollouts</h3>
<p>The <code>kubectl rollout</code> command provides the ability to check for the status of updates and, if required, roll back to a previous version.</p>
<pre><code>k set image deploy/nginx nginx=nginx:<span class="hljs-number">1.17</span><span class="hljs-number">.0</span> --record
k rollout status deploy/nginx
k rollout history deploy/nginx
# Rollback to previous version
k rollout undo deploy/nginx
# Rollback to revision number
k rollout undo deploy/nginx --to-revision=<span class="hljs-number">2</span>
k rollout pause deploy/nginx
k rollout resume deploy/nginx
k rollout restart deploy/nginx
kubectl run nginx-deploy --image=nginx:<span class="hljs-number">1.16</span> --replias=<span class="hljs-number">1</span> --record
</code></pre><h3 id="heading-scale-and-autoscale-command">Scale and autoscale command</h3>
<p>The <code>kubectl scale</code> command provides the functionality to scale up or scale down pods in a given deployment. </p>
<p>Using the <code>kubectl autoscale</code> command we can define the minimum number of pods that should be running for a given deployment and the maximum numbers of pods the deployment can scale to along with the scaling criteria like CPU percentage.</p>
<pre><code>k scale deploy/nginx --replicas=<span class="hljs-number">6</span>
k autoscale deploy/nginx --min=<span class="hljs-number">3</span> --max=<span class="hljs-number">9</span> --cpu-percent=<span class="hljs-number">80</span>
</code></pre><h3 id="heading-network-policy">Network policy</h3>
<p>In a Kubernetes cluster, all pods can communicate with all pods by default, which can be a security issue in some implementations. </p>
<p>To get around this issue, Kubernetes introduced Network Policies to allow or deny traffic to and from pods based on pod labels which are part of the pod spec.</p>
<p>The below example denies both the Ingress and Egress traffic for pods running in all namespaces. </p>
<pre><code>apiVersion: networking.k8s.io/v1
<span class="hljs-attr">kind</span>: NetworkPolicy
<span class="hljs-attr">metadata</span>:
  name: example
  <span class="hljs-attr">namespace</span>: <span class="hljs-keyword">default</span>
<span class="hljs-attr">spec</span>:
  podSelector: {}
  <span class="hljs-attr">policyTypes</span>:
  - Egress
  - Ingress
</code></pre><p>The below example denies both the Ingress and Egress traffic for pods running in all namespaces. But it allows access to DNS resolution services running on port 53.</p>
<pre><code>apiVersion: networking.k8s.io/v1
<span class="hljs-attr">kind</span>: NetworkPolicy
<span class="hljs-attr">metadata</span>:
  name: deny
  <span class="hljs-attr">namespace</span>: <span class="hljs-keyword">default</span>
<span class="hljs-attr">spec</span>:
  podSelector: {}
  <span class="hljs-attr">policyTypes</span>:
  - Egress
  - Ingress
  <span class="hljs-attr">egress</span>:
  - to:
    ports:
      - port: <span class="hljs-number">53</span>
        <span class="hljs-attr">protocol</span>: TCP
      - port: <span class="hljs-number">53</span>
        <span class="hljs-attr">protocol</span>: UDP
</code></pre><p>The below example denies Egress access to the metadata server running on IP address <code>169.256.169.256</code> in AWS EC2 Instances.</p>
<pre><code>apiVersion: networking.k8s.io/v1
<span class="hljs-attr">kind</span>: Ingress
<span class="hljs-attr">metadata</span>:
  name:cloud-metadata-deny
  <span class="hljs-attr">namespace</span>: <span class="hljs-keyword">default</span>
<span class="hljs-attr">spec</span>:
  podSelector: {}
  <span class="hljs-attr">policyTypes</span>:
  - Egress
  <span class="hljs-attr">egress</span>:
  - to:
      - ipBlock: 
          cidr: <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span>/<span class="hljs-number">0</span>
          <span class="hljs-attr">except</span>:
          - <span class="hljs-number">169.256</span><span class="hljs-number">.169</span><span class="hljs-number">.256</span>/<span class="hljs-number">32</span>
</code></pre><p>The below example allows Egress access to the metadata server running on IP address <code>169.256.169.256</code> in AWS EC2 Instances.</p>
<pre><code>apiVersion: networking.k8s.io/v1
<span class="hljs-attr">kind</span>: Ingress
<span class="hljs-attr">metadata</span>:
  name: cloud-metadata-accessor
  <span class="hljs-attr">namespace</span>: <span class="hljs-keyword">default</span>
<span class="hljs-attr">spec</span>:
  podSelector:
    matchLabels:
      role: metadata-accessor
  <span class="hljs-attr">policyTypes</span>:
  - Egress
  <span class="hljs-attr">egress</span>:
  - to:
    - ipBlock:
        cidr: <span class="hljs-number">169.256</span><span class="hljs-number">.169</span><span class="hljs-number">.256</span>/<span class="hljs-number">32</span>
</code></pre><h3 id="heading-static-analysis-using-kubesec">Static analysis using Kubesec</h3>
<p>Kubesec is a Static Analysis tool for analyzing the YAML files to find issues with the files.</p>
<pre><code>kubesec scan pod.yaml

# Using online kubesec API
curl -sSX POST --data-binary @pod.yaml https:<span class="hljs-comment">//v2.kubesec.io/scan</span>

# Running the API locally
kubesec http <span class="hljs-number">8080</span> &amp;

kubesec scan pod.yaml -o pod_report.json -o json
</code></pre><h3 id="heading-vulnerability-scanning-using-trivvy">Vulnerability scanning using Trivvy</h3>
<p>Trivvy is a Vulnerability Scanning tool that scans container images for security issues.</p>
<pre><code>trivy image nginx:<span class="hljs-number">1.18</span><span class="hljs-number">.0</span>
trivy image --severity CRITICAL nginx:<span class="hljs-number">1.18</span><span class="hljs-number">.0</span>
trivy image --severity CRITICAL, HIGH nginx:<span class="hljs-number">1.18</span><span class="hljs-number">.0</span>
trivy image --ignore-unfixed nginx:<span class="hljs-number">1.18</span><span class="hljs-number">.0</span>

# Scanning image tarball
docker save nginx:<span class="hljs-number">1.18</span><span class="hljs-number">.0</span> &gt; nginx.tar
trivy image --input archive.tar

# Scan and output results to file
trivy image --output python_alpine.txt python:<span class="hljs-number">3.10</span><span class="hljs-number">.0</span>a4-alpine
trivy image --severity HIGH --output /root/python.txt python:<span class="hljs-number">3.10</span><span class="hljs-number">.0</span>a4-alpine

# Scan image tarball
trivy image --input alpine.tar --format json --output /root/alpine.json
</code></pre><h3 id="heading-how-to-remove-unwanted-services">How to remove unwanted services</h3>
<p>The <code>systemctl</code> exposes the capabilities to start, stop, enable, disable and list services running on a Linux Virtual Machine.</p>
<p>List services:</p>
<pre><code>systemctl list-units --type service
</code></pre><p>Stop Service:</p>
<pre><code>systemctl stop apache2
</code></pre><p>Disable Service:</p>
<pre><code>systemctl disable apache2
</code></pre><p>Remove Service:</p>
<pre><code>apt remove apache2
</code></pre><h3 id="heading-runtime-classes">Runtime classes</h3>
<p>Kubernetes introduced the RuntimeClass feature in version <code>v1.12</code> for selecting the container runtime configuration. The container runtime configuration is used to run a pod's underlying containers. </p>
<p>Most Kubernetes clusters use the <code>dockershim</code> as the Runtime class for the running containers, but you can use different container Runtimes. </p>
<p>The <code>dockershim</code> has been deprecated in Kubernetes version <code>v1.20</code>, and will be removed in <code>v1.24</code>.</p>
<p>How to create a Runtime Class:</p>
<pre><code>apiversion: node.k8s.io/v1beta1
<span class="hljs-attr">kind</span>: RuntimeClass
<span class="hljs-attr">metadata</span>:
  name: gvisor
<span class="hljs-attr">handler</span>: runsc
</code></pre><p>How to use a runtime class for any given pod:</p>
<pre><code>apiVersion: v1
<span class="hljs-attr">kind</span>: Pod
<span class="hljs-attr">metadata</span>:
  labels:
    run: nginx
  <span class="hljs-attr">name</span>: nginx
<span class="hljs-attr">spec</span>:
  runtimeClassName: gvisor
  <span class="hljs-attr">containers</span>:
  - name: nginx
    <span class="hljs-attr">image</span>: nginx
</code></pre><h3 id="heading-rbac-commands">RBAC commands</h3>
<p>In Kubernetes, </p>
<blockquote>
<p>Role-based access control (RBAC) commands provide a method of regulating access to Kubernetes resources based on the roles of individual users or service accounts. (<a target="_blank" href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/">Source</a>)</p>
</blockquote>
<p>Here's how to create a role:</p>
<pre><code>kubectl create role developer --resource=pods --verb=create,list,get,update,<span class="hljs-keyword">delete</span> --namespace=development
</code></pre><p>How to create a role binding:</p>
<pre><code>kubectl create rolebinding developer-role-binding --role=developer --user=faizan --namespace=development
</code></pre><p>How to validate:</p>
<pre><code>kubectl auth can-i update pods --namespace=development --<span class="hljs-keyword">as</span>=faizan
</code></pre><p>How to create a cluster role:</p>
<pre><code>kubectl create clusterrole pvviewer-role --resource=persistentvolumes --verb=list
</code></pre><p>And how to create a Clusterrole Binding association with a service account:</p>
<pre><code>kubectl create clusterrolebinding pvviewer-role-binding --clusterrole=pvviewer-role --serviceaccount=<span class="hljs-keyword">default</span>:pvviewer
</code></pre><h3 id="heading-cluster-maintenance">Cluster maintenance</h3>
<p>You use the <code>kubectl drain</code> command to remove all running workloads (pods) from a given Node. </p>
<p>You use the <code>kubectl cordon</code> command to cordon a node to mark it as schedulable. </p>
<p>Ands you use the <code>kubectl uncordon</code> command to set the node as schedulable, meaning the Controller Manager can schedule new pods to the given node.</p>
<p>How to drain a node of all pods:</p>
<pre><code>kubectl drain node<span class="hljs-number">-1</span>
</code></pre><p>How to drain a node and ignore daemonsets:</p>
<pre><code>kubectl drain node01 --ignore-daemonsets
</code></pre><p>How to force drain:</p>
<pre><code>kubectl drain node02 --ignore-daemonsets --force
</code></pre><p>How to mark a node un-schedulable, so that no new pods can be scheduled on this node:</p>
<pre><code>kubectl cordon node<span class="hljs-number">-1</span>
</code></pre><p>Mark a node schedulable</p>
<pre><code>kubectl uncordon node<span class="hljs-number">-1</span>
</code></pre><h2 id="heading-cks-exam-tips">CKS Exam Tips</h2>
<p>The Kubernetes <code>kubectl get</code> command provides the user with an output flag, <code>-o</code> or <code>--output</code>, which helps us format the output in the form of JSON, yaml, wide, or custom-columns.</p>
<h3 id="heading-json-and-jsonpath">JSON and JSONPath</h3>
<p>How to output the contents of all the pods in the form of a JSON Object:</p>
<pre><code>kubectl get pods -o json
</code></pre><p>The JSONPath outputs a specific key from the JSON Object:</p>
<pre><code>kubectl get pods -o=jsonpath=<span class="hljs-string">'{@}'</span>
kubectl get pods -o=jsonpath=<span class="hljs-string">'{.items[0]}'</span>
</code></pre><p>The <code>.items[*]</code> is used where we have multiple objects, for instance multiple containers with a pod config:</p>
<pre><code># For list <span class="hljs-keyword">of</span> items use .items[*]
k get pods -o <span class="hljs-string">'jsonpath={.items[*].metadata.labels.version}'</span>
# For single item
k get po busybox -o jsonpath=<span class="hljs-string">'{.metadata}'</span>
k get po busybox -o jsonpath=<span class="hljs-string">"{['.metadata.name', '.metadata.namespace']}{'\n'}"</span>
</code></pre><p>The command returns the internal IP of a Node using JSONPath:</p>
<pre><code>kubectl get nodes -o=jsonpath=<span class="hljs-string">'{.items[*].status.addresses[?(@.type=="InternalIP")].address}'</span>
</code></pre><p>The command checks for equality on a specific key:</p>
<pre><code>kubectl get pod api-stag<span class="hljs-number">-765797</span>cf-lrd8q -o=jsonpath=<span class="hljs-string">'{.spec.volumes[?(@.name=="api-data")].persistentVolumeClaim.claimName}'</span>
kubectl get pod -o=jsonpath=<span class="hljs-string">'{.items[*].spec.tolerations[?(@.effect=="NoSchedule")].key}'</span>
</code></pre><p>Custom Columns are helpful in order to output specific fields:</p>
<pre><code>kubectl get pods -o=<span class="hljs-string">'custom-columns=PODS:.metadata.name,Images:.spec.containers[*].image'</span>
</code></pre><h2 id="heading-cks-exam-topics">CKS Exam Topics</h2>
<p>The CKS exam covers topics related to security in the Kubernetes ecosystem. Kubernetes security is a vast topic to cover in one article, so this article contains some of the topics covered in the exam.</p>
<h3 id="heading-how-to-secure-and-harden-container-images">How to secure and harden container images</h3>
<p>While designing container images to run your code, pay special attention to securing and hardening measures in order to prevent hacks and privilege escalation attacks. Keep the below points in mind while building the container images:</p>
<ol>
<li>Use specific package versions like <code>alpine:3.13</code>.</li>
<li>Don't run as root – use the <code>USER &lt;username&gt;</code> to block root access.</li>
<li>Make filesystem read-only in the <code>securityContext</code> using <code>readOnlyRootFilesystem: true</code></li>
<li>Remove shell access using <code>RUN rm -rf /bin/*</code></li>
</ol>
<h3 id="heading-how-to-minimise-os-footprint">How to minimise OS footprint</h3>
<h4 id="heading-conatiner-layers">Conatiner layers</h4>
<p>The instructions <code>RUN</code>, <code>COPY</code>, and <code>ADD</code> create container layers. Other instructions create temporary intermediate images and do not increase the size of the build. Instructions that create layers add to the size of the resulting image.</p>
<p>A typical Dockerfile looks like the one given below. It adds a single layer using the <code>RUN</code> instruction.</p>
<pre><code>FROM ubuntu

RUN apt-get update &amp;&amp; apt-get install -y golang-go

CMD [<span class="hljs-string">"sh"</span>]
</code></pre><h4 id="heading-multi-stage-builds">Multi-stage builds</h4>
<p>Multi-Stage builds leverage multiple <code>FROM</code> statements in the Dockerfile. The <code>FROM</code> instruction marks a new stage in the build. It combines multiple <code>FROM</code> statements allow to leverage from the previous build in order to selectively copy binaries over to the new build stage omitting the unnecessary binaries. The resulting Docker image is considerably smaller in size with a drastically reduced attack surface.</p>
<pre><code>FROM ubuntu:<span class="hljs-number">20.04</span> AS build
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update &amp;&amp; apt-get install -y golang-go
COPY app.go .
RUN CGO_ENABLED=<span class="hljs-number">0</span> go build app.go

FROM alpine:<span class="hljs-number">3.13</span>
RUN chmod a-w /etc
RUN addgroup -S appgroup &amp;&amp; adduser -S appuser -G appgroup -h /home/appuser
RUN rm -rf /bin<span class="hljs-comment">/*
COPY --from=build /app /home/appuser/
USER appuser
CMD ["/home/appuser/app"]</span>
</code></pre><h3 id="heading-how-to-limit-node-access">How to limit node access</h3>
<p>Access Control files contain sensitive information about users/groups in the Linux OS.</p>
<pre><code>#Stores information about the UID/GID, user shell, and home directory <span class="hljs-keyword">for</span> a user
/etc/passwd
#Stores the user password <span class="hljs-keyword">in</span> a hashed format
/etc/shadow
#Stores information about the group a user belongs
/etc/group
#Stored information about the Sudoers present <span class="hljs-keyword">in</span> the system
/etc/sudoers
</code></pre><p>Disabling a user account helps in securing access to a Node by disabling login to a given user account.</p>
<pre><code>usermod -s /bin/nologin &lt;username&gt;
</code></pre><p>Disabling the <code>root</code> user account is of special significance, as the root account has all the capabilities.</p>
<pre><code>usermod -s /bin/nologin root
</code></pre><p>Here's how to add a user with a home directory and shell:</p>
<pre><code>adduser --home /opt/faizanbashir --shell /bin/bash --uid <span class="hljs-number">2328</span> --ingroup admin faizanbashir
useradd -d /opt/faizanbashir -s /bin/bash -G admin -u <span class="hljs-number">2328</span> faizanbashir
</code></pre><p>How to delete the user account:</p>
<pre><code>userdel &lt;username&gt;
</code></pre><p>How to delete a group:</p>
<pre><code>groupdel &lt;groupname&gt;
</code></pre><p>How to add a user to a group:</p>
<pre><code>adduser &lt;username&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">groupname</span>&gt;</span></span>
</code></pre><p>How to remove a user from a group:</p>
<pre><code>#deluser faizanbashir admin
deluser &lt;username&gt; <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">groupname</span>&gt;</span></span>
</code></pre><p>How to set a password for a user:</p>
<pre><code>passwd &lt;username&gt;
</code></pre><p>How to elevate a user to sudoer:</p>
<pre><code>vim /etc/sudoers
&gt;&gt;&gt;
faizanbashir ALL=(ALL:ALL) ALL
</code></pre><p>How to enable sudo with no password:</p>
<pre><code>vim /etc/sudoers
&gt;&gt;&gt;
faizanbashir ALL=(ALL) NOPASSWD:ALL

visudo
usermod -aG sudo faizanbashir
usermod faizanbashir -G admin
</code></pre><h3 id="heading-ssh-hardening">SSH hardening</h3>
<h4 id="heading-how-to-disable-ssh">How to disable SSH</h4>
<p>The configuration given in the <code>/etc/ssh/sshd_config</code> can be leveraged to secure SSH access to Linux nodes. Setting the <code>PermitRootLogin</code> to <code>no</code> disables the root login on a node. </p>
<p>To enforce using a key to login and disabling login using passwords to nodes, you can set the <code>PasswordAuthentication</code> to <code>no</code>.</p>
<pre><code>vim /etc/ssh/sshd_config
&gt;&gt;
PermitRootLogin no
PasswordAuthentication no
&lt;&lt;
# Restart SSHD Service
systemctl restart sshd
</code></pre><p>How to set no login for the root user:</p>
<pre><code>usermod -s /bin/nologin root
</code></pre><p>SSH Copy user key / Passwordless SSH:</p>
<pre><code>ssh-copy-id -i ~<span class="hljs-regexp">/.ssh/i</span>d_rsa.pub faizanbashir@node01
ssh faizanbashir@node01
</code></pre><h3 id="heading-how-to-remove-obsolete-packages-and-services">How to remove obsolete packages and services</h3>
<p>Here's how you can list all services running on an Ubuntu machine:</p>
<pre><code>systemctl list-units --type service
systemctl list-units --type service --state running
</code></pre><p>How to stop, disable, and remove a service:</p>
<pre><code>systemctl stop apache2
systemctl disable apache2
apt remove apache2
</code></pre><h3 id="heading-how-to-restrict-kernel-modules">How to restrict kernel modules</h3>
<p>In Linux, Kernel modules are pieces of code that can be loaded and unloaded into the kernel upon demand. They extend the functionality of the kernel without the need to reboot the system. A module can be configured as built-in or loadable.</p>
<p>How to list all Kernel Modules:</p>
<pre><code>lsmod
</code></pre><p>How to manually load modules into a Kernel:</p>
<pre><code>modprobe pcspkr
</code></pre><p>How to blacklist a module: (Reference: CIS Benchmarks -&gt; 3.4 Uncommon Network Protocols)</p>
<pre><code>cat /etc/modprobe.d/blacklist.conf
&gt;&gt;&gt;
blacklist sctp
blacklist dccp

# Shutdown <span class="hljs-keyword">for</span> changes to take effect
shutdown -r now

# Verify
lsmod | grep dccp
</code></pre><h3 id="heading-how-to-identify-and-disable-open-ports">How to identify and disable open ports</h3>
<p>How to check for open ports:</p>
<pre><code>netstat -an | grep -w LISTEN
netstat -natp | grep <span class="hljs-number">9090</span>

nc -zv &lt;hostname|IP&gt; <span class="hljs-number">22</span>
nc -zv &lt;hostname|IP&gt; <span class="hljs-number">10</span><span class="hljs-number">-22</span>

ufw deny <span class="hljs-number">8080</span>
</code></pre><p>How to check port usage:</p>
<pre><code>/etc/services | grep -w <span class="hljs-number">53</span>
</code></pre><p>Here's the reference doc for a <a target="_blank" href="https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#control-plane-node-s">list of open ports</a>.</p>
<h3 id="heading-how-to-restrict-network-access">How to restrict network access</h3>
<h4 id="heading-how-to-identity-a-service-running-on-port">How to identity a service running on port:</h4>
<pre><code>systemctl status ssh
cat /etc/services | grep ssh
netstat -an | grep <span class="hljs-number">22</span> | grep -w LISTEN
</code></pre><h4 id="heading-ufw-firewall">UFW firewall</h4>
<p>Uncomplicated Fire Wall (UFW) is a tool for managing firewall rules in Arch Linux, Debian, or Ubuntu. UFW lets you allow and block traffic on a given port and from a given source.</p>
<p>Here's how to install UFW Firewall:</p>
<pre><code>apt-get update
apt-get install ufw
systemctl enable ufw
systemctl start ufw
ufw status
ufw status numbered
</code></pre><p>How to allow all outbound and inbound connections:</p>
<pre><code>ufw <span class="hljs-keyword">default</span> allow outgoing
ufw <span class="hljs-keyword">default</span> allow incoming
</code></pre><p>How to allow rules:</p>
<pre><code>ufw allow <span class="hljs-number">22</span>
ufw allow <span class="hljs-number">1000</span>:<span class="hljs-number">2000</span>/tcp
ufw allow <span class="hljs-keyword">from</span> <span class="hljs-number">172.16</span><span class="hljs-number">.238</span><span class="hljs-number">.5</span> to any port <span class="hljs-number">22</span> proto tcp
ufw allow <span class="hljs-keyword">from</span> <span class="hljs-number">172.16</span><span class="hljs-number">.238</span><span class="hljs-number">.5</span> to any port <span class="hljs-number">80</span> proto tcp
ufw allow <span class="hljs-keyword">from</span> <span class="hljs-number">172.16</span><span class="hljs-number">.100</span><span class="hljs-number">.0</span>/<span class="hljs-number">28</span> to any port <span class="hljs-number">80</span> proto tcp
</code></pre><p>How to deny rules:</p>
<pre><code>ufw deny <span class="hljs-number">8080</span>
</code></pre><p>How to enable and activate the Firewall:</p>
<pre><code>ufw enable
</code></pre><p>How to delete rules:</p>
<pre><code>ufw <span class="hljs-keyword">delete</span> deny <span class="hljs-number">8080</span>
ufw <span class="hljs-keyword">delete</span> &lt;rule-line&gt;
</code></pre><p>How to reset rules:</p>
<pre><code>ufw reset
</code></pre><h3 id="heading-linux-syscalls">Linux Syscalls</h3>
<p>Linux Syscalls are used to make requests from user space into the Linux kernel. For instance, while creating a file, the userspace makes a request to the Linux Kernel to create the file. </p>
<p>Kernel Space has the following:</p>
<ul>
<li>Kernel Code</li>
<li>Kernel Extensions</li>
<li>Device Drivers</li>
</ul>
<h4 id="heading-how-to-trace-syscalls-using-strace">How to trace Syscalls using Strace</h4>
<p>Here's how you can trace syscalls using strace:</p>
<pre><code>which strace
strace touch /tmp/error.log
</code></pre><p>How to get the PID of a service:</p>
<pre><code>pidof sshd
strace -p &lt;pid&gt;
</code></pre><p>How to list all syscalls made during an operation:</p>
<pre><code>strace -c touch /tmp/error.log
</code></pre><p>How to consolidate listing syscalls: (Count and summarise)</p>
<pre><code>strace -cw ls /
</code></pre><p>How to follow a PID and consolidate:</p>
<pre><code>strace -p <span class="hljs-number">3502</span> -f -cw
</code></pre><h3 id="heading-aquasec-tracee">AquaSec Tracee</h3>
<p>AquaSec Tracee was created by Aqua Security which uses eBPF to trace events in containers. Tracee uses eBPF (Extended Berkeley Packet Filter) at runtime directly in the kernel space without interfering with the kernel source or loading any kernel modules.</p>
<ul>
<li>Binary stored at <code>/tmp/tracee</code></li>
<li>Needs access to the following, in read-only mode if run using a container with <code>--privileged</code> capability:<ul>
<li><code>/tmp/tracee</code> -&gt; Default workspace</li>
<li><code>/lib/modules</code> -&gt; Kernel Headers</li>
<li><code>/usr/src</code> -&gt; Kernel Headers</li>
</ul>
</li>
</ul>
<p>How to fun Tracee in a Docker container:</p>
<pre><code>docker run --name tracee --rm --privileged --pid=host \
  -v /lib/modules/:<span class="hljs-regexp">/lib/m</span>odules/:ro -v /usr/src/:<span class="hljs-regexp">/usr/</span>src/ro \
  -v /tmp/tracee:<span class="hljs-regexp">/tmp/</span>tracee aquasec/tracee:<span class="hljs-number">0.4</span><span class="hljs-number">.0</span> --trace comm=ls

# List syscalls made by all the <span class="hljs-keyword">new</span> process on the host
docker run --name tracee --rm --privileged --pid=host \
  -v /lib/modules/:<span class="hljs-regexp">/lib/m</span>odules/:ro -v /usr/src/:<span class="hljs-regexp">/usr/</span>src/ro \
  -v /tmp/tracee:<span class="hljs-regexp">/tmp/</span>tracee aquasec/tracee:<span class="hljs-number">0.4</span><span class="hljs-number">.0</span> --trace pid=<span class="hljs-keyword">new</span>

# List syscalls made <span class="hljs-keyword">from</span> any <span class="hljs-keyword">new</span> container
docker run --name tracee --rm --privileged --pid=host \
  -v /lib/modules/:<span class="hljs-regexp">/lib/m</span>odules/:ro -v /usr/src/:<span class="hljs-regexp">/usr/</span>src/ro \
  -v /tmp/tracee:<span class="hljs-regexp">/tmp/</span>tracee aquasec/tracee:<span class="hljs-number">0.4</span><span class="hljs-number">.0</span> --trace container=<span class="hljs-keyword">new</span>
</code></pre><h3 id="heading-how-to-restrict-syscalls-with-seccomp">How to restrict Syscalls with Seccomp</h3>
<p><strong>SECCOMP</strong> – Secure Computing Mode – is a Linux Kernel level feature that you can use to sandbox applications to only use the syscalls they need.</p>
<p>How to check support for seccomp:</p>
<pre><code>grep -i seccomp /boot/config-$(uname -r)
</code></pre><p>How to test to change system time:</p>
<pre><code>docker run -it --rm docker/whalesay /bin/sh
# date -s <span class="hljs-string">'19 APR 2013 22:00:00'</span>

ps -ef
</code></pre><p>How to check seccomp status for any PID:</p>
<pre><code>grep -i seccomp /proc/<span class="hljs-number">1</span>/status
</code></pre><p>Seccomp modes:</p>
<ul>
<li>Mode 0: Disabled</li>
<li>Mode 1: Strict</li>
<li>Mode 2: Filtered</li>
</ul>
<p>The following configuration is used to whitelist syscalls. The whitelist profile is secure but syscalls have to be selectively enabled as it blocks all syscalls by default.</p>
<pre><code>{
  <span class="hljs-string">"defaultAction"</span>: <span class="hljs-string">"SCMP_ACT_ERRNO"</span>,
  <span class="hljs-string">"architectures"</span>: [
    <span class="hljs-string">"SCMP_ARCH_X86_64"</span>,
    <span class="hljs-string">"SCMP_ARCH_X86"</span>,
    <span class="hljs-string">"SCMP_ARCH_X32"</span>
  ],
  <span class="hljs-string">"syscalls"</span>: [
    {
      <span class="hljs-string">"names"</span>: [
        <span class="hljs-string">"&lt;syscall-1&gt;"</span>,
        <span class="hljs-string">"&lt;syscall-2&gt;"</span>,
        <span class="hljs-string">"&lt;syscall-3&gt;"</span>
      ],
      <span class="hljs-string">"action"</span>: <span class="hljs-string">"SCMP_ACT_ALLOW"</span>
    }
  ]
}
</code></pre><p>The following configuration is used to blacklist syscalls. The blacklist profile has a greater attack surface than the whitelist. </p>
<pre><code>{
  <span class="hljs-string">"defaultAction"</span>: <span class="hljs-string">"SCMP_ACT_ALLOW"</span>,
  <span class="hljs-string">"architectures"</span>: [
    <span class="hljs-string">"SCMP_ARCH_X86_64"</span>,
    <span class="hljs-string">"SCMP_ARCH_X86"</span>,
    <span class="hljs-string">"SCMP_ARCH_X32"</span>
  ],
  <span class="hljs-string">"syscalls"</span>: [
    {
      <span class="hljs-string">"names"</span>: [
        <span class="hljs-string">"&lt;syscall-1&gt;"</span>,
        <span class="hljs-string">"&lt;syscall-2&gt;"</span>,
        <span class="hljs-string">"&lt;syscall-3&gt;"</span>
      ],
      <span class="hljs-string">"action"</span>: <span class="hljs-string">"SCMP_ACT_ERRNO"</span>
    }
  ]
}
</code></pre><p>The Docker seccomp profile blocks 60 of the 300+ syscalls on the x86 architecture.</p>
<p>How to use seccomp profiles with Docker:</p>
<pre><code>docker run -it --rm --security-opt seccomp=<span class="hljs-regexp">/root/</span>custom.json docker/whalesay /bin/sh
</code></pre><p>How to allow all syscalls with the container:</p>
<pre><code>docker run -it --rm --security-opt seccomp=unconfined docker/whalesay /bin/sh

# Verify
grep -i seccomp /proc/<span class="hljs-number">1</span>/status

# Output should be:
Seccomp:         <span class="hljs-number">0</span>
</code></pre><p>How to use Docker container to get container runtime related information:</p>
<pre><code>docker run r.j3ss.co/amicontained amicontained
</code></pre><h4 id="heading-seccomp-in-kubernetes">Seccomp in Kubernetes</h4>
<p>Secure computing mode (SECCOMP) is a Linux kernel feature. You can use it to restrict the actions available within the container. <a target="_blank" href="https://kubernetes.io/docs/tutorials/clusters/seccomp">Seccomp documentation</a></p>
<p>How to run amicontained in Kubernetes:</p>
<pre><code>kubectl run amicontained --image r.j3ss.co/amicontained amicontained -- amicontained
</code></pre><p>As of version <code>v1.20</code> Kubernetes does not implement seccomp by default.</p>
<p>Seccomp 'RuntimeDefault' docker profile in Kubernetes:</p>
<pre><code>apiVersion: v1
<span class="hljs-attr">kind</span>: Pod
<span class="hljs-attr">metadata</span>:
  labels:
    run: amicontained
  <span class="hljs-attr">name</span>: amicontained
<span class="hljs-attr">spec</span>:
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  <span class="hljs-attr">containers</span>:
  - args:
    - amicontained
    <span class="hljs-attr">image</span>: r.j3ss.co/amicontained
    <span class="hljs-attr">name</span>: amicontained
    <span class="hljs-attr">securityContext</span>:
      allowPrivilegeEscalation: <span class="hljs-literal">false</span>
</code></pre><p>Default seccomp location in kubelets</p>
<pre><code>/<span class="hljs-keyword">var</span>/lib/kubelet/seccomp
</code></pre><p>How to create a seccomp profile in node:</p>
<pre><code>mkdir -p /<span class="hljs-keyword">var</span>/lib/kubelet/seccomp/profiles

# Add a profile <span class="hljs-keyword">for</span> audit
vim /<span class="hljs-keyword">var</span>/lib/kubelet/seccomp/profiles/audit.json
&gt;&gt;&gt;
{
  <span class="hljs-attr">defaultAction</span>: <span class="hljs-string">"SCMP_ACT_LOG"</span>
}

# Add a profile <span class="hljs-keyword">for</span> violations (Blocks all syscalls by <span class="hljs-keyword">default</span>, will <span class="hljs-keyword">let</span> nothing run)
vim /<span class="hljs-keyword">var</span>/lib/kubelet/seccomp/profiles/violation.json
&gt;&gt;&gt;
{
  <span class="hljs-attr">defaultAction</span>: <span class="hljs-string">"SCMP_ACT_ERRNO"</span>
}
</code></pre><p>Local seccomp profile – this file should exist locally on a node to be able to work:</p>
<pre><code>...
securityContext:
  seccompProfile:
    type: Localhost
    <span class="hljs-attr">localhostProfile</span>: profiles/audit.json
...
</code></pre><p>The above profile will enable syscalls to be saved to a file.</p>
<pre><code>grep syscall /<span class="hljs-keyword">var</span>/log/syslog
</code></pre><p>How to map syscall numbers to syscall name:</p>
<pre><code>grep -w <span class="hljs-number">35</span> /usr/include/asm/unistd_64.h

# OR
grep -w <span class="hljs-number">35</span> /usr/include/asm-generic/unistd.h
</code></pre><h3 id="heading-apparmor">AppArmor</h3>
<p>AppArmor is a Linux security module that is used to confine a program to a limited set of resources.</p>
<p>How to install AppArmor utils:</p>
<pre><code>apt-get install apparmor-utils
</code></pre><p>How to check if AppArmor is running and enabled:</p>
<pre><code>systemctl status apparmor

cat /sys/<span class="hljs-built_in">module</span>/apparmor/parameters/enabled
Y
</code></pre><p>The AppArmor profiles are stored at:</p>
<pre><code>cat /etc/apparmor.d/root.add_data.sh
</code></pre><p>How to list AppArmor profiles:</p>
<pre><code>cat /sys/kernel/security/apparmor/profiles
</code></pre><p>How to deny all file write profiles:</p>
<pre><code>profile apparmor-deny-write flags=(attach_disconnected) {
  file,
  # Deny all file writes.
  deny <span class="hljs-comment">/** w,
}</span>
</code></pre><p>How to deny write to <code>/proc</code> files:</p>
<pre><code>profile apparmor-deny-proc-write flags=(attach_disconnected) {
  file,
  # Deny all file writes.
  deny /proc<span class="hljs-comment">/* w,
}</span>
</code></pre><p>How to deny remount root FS:</p>
<pre><code>profile apparmor-deny-remount-root flags=(attach_disconnected) {

  # Deny all file writes.
  deny mount options=(ro, remount) -&gt; /,
}
</code></pre><p>How to check profile status:</p>
<pre><code>aa-status
</code></pre><p>Profile load modes</p>
<ul>
<li><code>Enforce</code>, monitor and enforce the rules</li>
<li><code>Complain</code>, will not enforce the rules but logs them as events</li>
<li><code>Unconfined</code>, will not enforce or log events</li>
</ul>
<p>How to check if a profile is valid:</p>
<pre><code>apparmor_parser /etc/apparmor.d/root.add_data.sh
</code></pre><p>How to disable a profile:</p>
<pre><code>apparmor_parser -R /etc/apparmor.d/root.add_data.sh
ln -s /etc/apparmor.d/root.add_data.sh /etc/apparmor.d/disable/
</code></pre><p>How to generate a profile and answer the series of questions that follow:</p>
<pre><code>aa-genprof /root/add_data.sh
</code></pre><p>How to generate a profile for a command:</p>
<pre><code>aa-genprof curl
</code></pre><p>How to disable profile from logs:</p>
<pre><code>aa-logprof
</code></pre><h4 id="heading-how-to-use-apparmor-in-kubernetes">How to use AppArmor in Kubernetes</h4>
<p>To use AppArmor with Kubernetes, the following prerequisites must be met:</p>
<ul>
<li>Kubernetes version should be greater than <code>1.4</code></li>
<li>AppArmor Kernel module should be enabled</li>
<li>AppArmor profile should be loaded in the kernel</li>
<li>Container runtime should be supported</li>
</ul>
<p>Sample usage in Kubernetes:</p>
<pre><code>apiVersion: v1
<span class="hljs-attr">kind</span>: Pod
<span class="hljs-attr">metadata</span>:
  name: ubuntu-sleeper
  <span class="hljs-attr">annotations</span>:
    container.apparmor.security.beta.kubernetes.io/&lt;container-name&gt;: localhost/&lt;profile-name&gt;
spec:
  containers:
  - name: ubuntu-sleeper
    image: ubuntu
    command: ["sh", "-c", "echo 'Sleeping for an hour!' &amp;&amp; sleep 1h"]
</code></pre><p><strong>Note</strong>: The container should run in a node containing the AppArmor profile.</p>
<h3 id="heading-linux-capabilities">Linux capabilities</h3>
<p>The Linux capabilities feature breaks up the privileges available to processes run as the <code>root</code> user into smaller groups of privileges. This way a process running with <code>root</code> privilege can be limited to get only the minimal permissions it needs to perform its operation. </p>
<p>Docker supports the Linux capabilities as part of the Docker run command: with <code>--cap-add</code> and <code>--cap-drop</code>. By default, a container is started with several capabilities that are allowed by default and can be dropped. Other permissions can be added manually. </p>
<p>Both <code>--cap-add</code> and <code>--cap-drop</code> support the ALL value, to allow or drop all capabilities. By default Docker containers run with 14 capabilities.</p>
<ul>
<li>Kernel &lt; 2.2<ul>
<li>Privileged Process</li>
<li>Unprivileged Process</li>
</ul>
</li>
<li>Kernel &gt;= 2.2<ul>
<li>Privileged Process<ul>
<li><code>CAP_CHOWN</code></li>
<li><code>CAP_SYS_TIME</code></li>
<li><code>CAP_SYS_BOOT</code></li>
<li><code>CAP_NET_ADMIN</code></li>
</ul>
</li>
</ul>
</li>
</ul>
<p><a target="_blank" href="https://man7.org/linux/man-pages/man7/capabilities.7.html">Refer to this document for the full list of Linux Capabilities</a>.</p>
<p>How to check what capabilities a command needs:</p>
<pre><code>getcap /usr/bin/ping
</code></pre><p>How to get process capabilities:</p>
<pre><code>getpcaps &lt;pid&gt;
</code></pre><p>How to add security capabilities:</p>
<pre><code>apiVersion: v1
<span class="hljs-attr">kind</span>: Pod
<span class="hljs-attr">metadata</span>:
  name: ubuntu-sleeper
<span class="hljs-attr">spec</span>:
  containers:
  - name: ubuntu-sleeper
    <span class="hljs-attr">image</span>: ubuntu
    <span class="hljs-attr">command</span>: [<span class="hljs-string">"sleep"</span>, <span class="hljs-string">"1000"</span>]
    <span class="hljs-attr">securityContext</span>:
      capabilities:
        add: [<span class="hljs-string">"SYS_TIME"</span>]
        <span class="hljs-attr">drop</span>: [<span class="hljs-string">"CHOWN"</span>]
</code></pre><h2 id="heading-how-to-prepare-for-the-exam">How to Prepare for the Exam</h2>
<p>CKS is considered a pretty tough exam. But based on my experience I think that, given good enough practice and if you understand the concepts the exam covers, it'll be pretty manageable within two hours. </p>
<p>You definitely need to understand the underlying Kubernetes concepts. And since a prerequisite for CKS is to pass the CKA exam, you should have a strong understanding of Kubernetes and how it functions before attempting the CKS. </p>
<p>In addition, to pass the CKS, you need to understand the threats and security implications introduced by container orchestration.</p>
<p>The introduction of the CKS exam is an indication that the security of containers should not be taken lightly. Security mechanisms should always be in place to thwart attacks on Kubernetes clusters. </p>
<p>The <a target="_blank" href="https://www.wired.com/story/cryptojacking-tesla-amazon-cloud/">Tesla cryptocurrency hack</a> that was thanks to an unprotected Kubernetes dashboard brings to light the risks associated with Kubernetes or any other container orchestration engine. <a target="_blank" href="https://hackerone.com/kubernetes?type=team">Hackerone has a Kubernetes bounty page</a> listing the source code repos used in a standard Kubernetes cluster.</p>
<h2 id="heading-practice-practice-and-practice">Practice, Practice, and Practice!</h2>
<p>Practice is the key to cracking the exam, I personally found that the exam simulators by KodeKloud and Killer.sh were immensely helpful for me.</p>
<p>I didn't have as much time to prepare for the CKS exam as I had for the CKA exam, but I was working on Kubernetes in my day job so I'd become really comfortable with it. </p>
<p>Practice is the key to success. Best of luck with the exam!</p>
<p><em>You can read this and other articles at <a target="_blank" href="https://faizanbashir.me/rough-guide-to-qualifying-the-cks-exam-in-a-hurry">faizanbashir.me</a></em></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How I Passed the CompTIA Linux+ Exam ]]>
                </title>
                <description>
                    <![CDATA[ By Clark Jason Ngo Summary of this article: The backstory: why CompTIA Linux+ exam. Review of learning resources: what is good and what is not good. Retrospective on studying: what worked and did not work. My experience during the exam: how the test... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/the-linux-exam-story/</link>
                <guid isPermaLink="false">66d45e26230dff01669057e1</guid>
                
                    <category>
                        <![CDATA[ comptia ]]>
                    </category>
                
                    <category>
                        <![CDATA[ exam  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ learning ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Linux ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 30 Apr 2020 10:01:32 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/04/Screen-Shot-2020-04-29-at-10.33.10-PM.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Clark Jason Ngo</p>
<h3 id="heading-summary-of-this-article">Summary of this article:</h3>
<ul>
<li>The backstory: why CompTIA Linux+ exam.</li>
<li>Review of learning resources: what is good and what is not good.</li>
<li>Retrospective on studying: what worked and did not work.</li>
<li>My experience during the exam: how the test was conducted and how I felt.</li>
<li>My approach during the exam: what strategies to use and mindset to have.</li>
<li>Getting an awesome badge: what it looks like and what's in it for me?</li>
<li>Bonus: as most of my materials are sponsored by the school, I've looked for free content for you to study for the exam, such as <a target="_blank" href="https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard">filesystem hierarchy</a>, <a target="_blank" href="https://refspecs.linuxfoundation.org/FHS_3.0/fhs-3.0.html#binEssentialUserCommandBinaries">basic linux commands</a>, using <a target="_blank" href="https://aws.amazon.com/mp/linux/">AWS EC2 Ubuntu</a> as your Linux environment.  I also created a flash card in Trello, available <a target="_blank" href="https://trello.com/b/viGl7wam/linux-prep">here</a>.  Disclaimer: free content might not be sufficient. </li>
<li>Exam objectives: <a target="_blank" href="https://www.comptia.jp/pdf/comptia-linux-xk0-004-exam-objectives.pdf">Official CompTIA Linux+ Exam Objectives</a>. </li>
</ul>
<h3 id="heading-tldr-exam-tips-i-had-no-professional-experience-with-linux">TLDR exam tips (I had no professional experience with Linux):</h3>
<ul>
<li>Focus on the Activity Section of the CompTIA Study Guide and follow along with your own Linux environment.</li>
<li>Practice on Performance-Based Questions (PBQs). They show around 10 choices that all <em>look</em> correct.</li>
<li>Play around with Linux command combinations using piping (|)</li>
<li>Configure IP tables, firewall, and troubleshooting.</li>
<li>Learn the configuration steps, boot process, and backing up files.</li>
<li>Basic bash scripting and regular expressions.</li>
</ul>
<p><em>Read until the end for tips on how to have the correct mindset and strategies to answer difficult questions. Also, a video of me summarizing this article during a club meeting at our school is available at the bottom of the article. Do check the video out as it has a Q&amp;A section towards the end.</em></p>
<p>I'd like to start off with a big thank you to <a target="_blank" href="https://ciae.cityu.edu/programs/">School of Technology and Computing</a> of <a target="_blank" href="https://www.cityu.edu/">City University of Seattle</a> (CityU). They provided me with a job, career growth, and sponsored my CompTIA learning materials and exam voucher. </p>
<p>As an F-1 Student Visa holder with limited job opportunities, this allowed me to earn extra income, of which I <a target="_blank" href="https://www.freecodecamp.org/donate/">donate</a> a portion to freeCodeCamp on a monthly basis. </p>
<p>This is a loose continuation from my story: <em><a target="_blank" href="https://www.freecodecamp.org/news/cjn-why-i-abandoned-my-mba-to-get-a-masters-in-computer-science/">Why I abandoned my MBA to get a master's in Computer Science</a></em>.</p>
<p><img src="https://cdn-media-1.freecodecamp.org/images/0*cSvQ_M7qvgXFrIrA.jpg" alt="Image" width="540" height="210" loading="lazy">
<em>City University of Seattle Campus</em></p>
<h2 id="heading-why-comptia-linux">Why CompTIA Linux+?</h2>
<p>In July 2019, our school, with the help of our director of external relations, landed a contract with Amazon Web Services (AWS) and Washington Technology Industry Association (WTIA), called the AWS Apprenticeship Program (AAP). </p>
<p>We had the opportunity to train 23 military veterans and veteran spouses. Their requirement was to pass CompTIA Linux+ Exam and CityU's Full Stack System Developer Program which includes CompTIA Linux+ Exam preparation. Once they met both criteria, they'd be able to transition to on-the-job training with AWS. </p>
<p>My role at the time was a Lead Teaching Assistant (TA) and I was tasked to help build the Dean's program proposal. I coordinated with 6 other TAs to build the courses, which consisted the following: Linux I, Linux II, Networking, Web Development, JavaScript/TypeScript, Full Stack - MEAN Stack, Python, and Full Stack - Django.</p>
<p>As this was our first contract, we were building the plane while trying to fly it.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-295.png" alt="Image" width="600" height="400" loading="lazy">
<em>Picture looks fun! But not in real life lol!</em></p>
<h3 id="heading-we-utilized-the-following-resources-for-our-linux-operating-system-course">We utilized the following resources for our Linux Operating System course:</h3>
<ul>
<li>Textbook: Pro Bash Programming: Scripting the GNU/Linux Shell, Second Edition, by Chris F. A. Johnson, Jayant Varma </li>
<li>Student's Linux environment: AWS EC2 Instance with Ubuntu</li>
<li>Virtual Lab: InfoSec Learning</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-296.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-what-i-learned">What I learned</h3>
<ul>
<li>A lot of bash scripting exercises and coding challenges</li>
<li>How to SSH to a remote server (EC2 Instance)</li>
<li>Various Linux commands and configuration setups related to CompTIA Linux+</li>
</ul>
<p>After a few weeks into the program, we researched more and listened to student feedback. Turns out we were doing too much bash scripting and lacked on CompTIA Linux+ Exam preparation.</p>
<blockquote>
<p>The students were in hell during the first few weeks of bash scripting</p>
</blockquote>
<p>We immediately partnered with CompTIA to get CompTIA Linux+ Exam Study materials at bulk price. We pivoted hard and changed parts of our program to integrate the new study materials.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-299.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cool badge</em></p>
<blockquote>
<p>Good thing our department was practicing Agile methodology and it made us very nimble.</p>
</blockquote>
<h3 id="heading-the-new-resources-are-as-follows">The new resources are as follows:</h3>
<ul>
<li>CertMaster Learn - includes eBook, Performance-Based Question (PBQ), and CompTIA Videos (Note: This was last year. If you purchased this year, you won't have the PBQs, but you get a new interface, and an additional practice test).</li>
<li>CertMaster Practice - multiple-choice questions on steroids. Once you've accumulated a good amount of wrong answers, you'd get feedback on why your answers are wrong and it explains the other choices as well. Then, it pushes your progress bar back.</li>
<li>CertMaster Labs - shorter lab activities compared to InfoSec Labs.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-298.png" alt="Image" width="600" height="400" loading="lazy">
<em>The CompTIA Linux+ Learning bundle</em></p>
<h3 id="heading-my-thoughts-on-the-new-resources">My thoughts on the new resources</h3>
<p>I read the eBook from top to bottom and it was helpful to obtain an overview. However, I wasn't able to retain any knowledge from reading it. I breezed through both the CertMaster Practice and CertMaster Labs and I gained nothing as well. </p>
<blockquote>
<p>What's wrong with me? Hmm..</p>
</blockquote>
<p>Because of an opportunity to teach the JavaScript/TypeScript course in the AAP program and the unfortunate event of my dad's passing, my road to Linux+ Exam was eventually derailed and forgotten.</p>
<blockquote>
<p>Man.... What a bummer...</p>
</blockquote>
<h2 id="heading-fast-forward-to-the-end-of-the-aws-apprenticeship-program">Fast forward to the end of the AWS Apprenticeship Program</h2>
<p>In November 2019, we successfully transitioned all 23 students! A 100%! We were the only partner school to have done that.</p>
<p>Most credit goes to the School of Technology &amp; Computing Dean's repeated quotes of "leave no man behind" - similar to the soldier's creed: "I will never leave a fallen comrade behind", and "we stay together, we survive" (from the movie Gladiator).</p>
<p>The program's success was largely attributed to TAs, who supported the students since Day 1.</p>
<p>We asked for feedback from our students on what worked and what did not in regards to the CompTIA Linux+ materials. We got the following:</p>
<ul>
<li>Focus on Activity Section of the Study Guide</li>
<li>Do the virtual labs repeatedly</li>
<li>Going through the practice exam is not effective</li>
<li>Watch ITPro.tv videos (which we were not able to provide that time)</li>
</ul>
<p>I did not study for the Linux+ Exam for several months as I focused on learning the MEAN Stack (especially the Angular front end framework). I regularly tackled leetcode coding challenges to prepare for software developer job interviews. </p>
<p>I was also finishing my capstone project: <a target="_blank" href="https://www.freecodecamp.org/news/cjn-understanding-mean-stack-through-diagrams/"><em>Software Documentation and Architectural Analysis of Full Stack Development</em></a>, and teaching two classes: Information Systems, and Data Management Communications and Networking.</p>
<blockquote>
<p>No time... no time at all... or was it just excuses?</p>
</blockquote>
<p>When I was nearing the end of my last quarter, I felt guilty and started studying again for the Linux+ Exam. </p>
<blockquote>
<p>This time, a new plan of attack. </p>
</blockquote>
<p>I started reading the eBook again from top to bottom. What was different the second time around was that for every theory, definition, command, option, subcommands, etc. that I'd encounter, I would create a flash card in Trello (available <a target="_blank" href="https://trello.com/b/viGl7wam/linux-prep">here</a>). I used this to train with friends to do a pop quiz and execute commands in the Linux terminal as well. </p>
<p>On my own, I would have my own Linux environment following along with the Activity Section of the eBook. This really helped me retain my knowledge on Linux commands and configurations. I also incorporated using Linux commands in my personal laptop with MacBook Pro, as MacOS has Unix-like terminal.</p>
<p>I utilized the CertMaster Practice Exam again. And this time, I had a friend to go over and discuss why each choice was right or wrong, using the process of elimination.</p>
<blockquote>
<p>It seems like doing hands-on and having a discussion with a friend truly helps you master a topic.</p>
</blockquote>
<p>I really didn't like the CertMaster Labs and did not use it during my study.</p>
<h3 id="heading-i-hesitated-to-study-the-following">I hesitated to study the following:</h3>
<ul>
<li>bash scripting - I'm a software developer and I know how to code already. I have built bash scripts to boost my productivity, from class notes to web applications.</li>
<li>version control - I've been using git and GitHub in my classes and personal projects.</li>
<li>containers and orchestration - I have a good foundation as I've been reading DevOps books.</li>
</ul>
<h2 id="heading-the-binge-worthy-itprotv-videos">The Binge-Worthy ITPro.tv Videos</h2>
<blockquote>
<p>I accidentally discovered it. It was timely and effective.</p>
</blockquote>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-304.png" alt="Image" width="600" height="400" loading="lazy">
<em>where you can binge-watch IT videos</em></p>
<p>At the start of April 2020, we got news of incoming AAP students. The Dean asked me to check the CompTIA store again for materials, and find out what these ITPro.tv videos were all about. </p>
<p>At first, I was reluctant to even purchase the videos because I remembered the CompTIA Study Guide having the ITPro.tv logo at the start of their videos. I started calculating the total hours of the CompTIA Study Guide videos. The total duration was only 22 minutes. </p>
<p>This was a big difference compared to the standalone ITPro.tv videos with 16 hours of content. I went ahead and purchased it (with reimbursement of course).</p>
<p>And boy, I did not regret it. Those videos were fantastic. They dove deeper into the topics and explained the commands throughly with the help of a co-host to ask why we needed to use those commands. </p>
<p>The average duration of a video is about 15 minutes. A big contrast compared to the other resource, which averaged about 2 minutes per video.</p>
<p>I started picking videos to watch based on the topics that I knew I couldn't explain to anyone. I combined this strategy with the multiple-choice-on-steroids CertMaster Practice to fill in my knowledge gaps.</p>
<p>In the middle of April 2020, I scheduled my CompTIA Linux+ Exam Online Testing. They created the online testing environment due to the pandemic. As it was nearing the scheduled date, I relaxed my study patterns and limited myself to watching the ITPro.tv videos.</p>
<h2 id="heading-exam-procedures">Exam Procedures</h2>
<p>The online exam requires you to abide by the following procedures:</p>
<ul>
<li>have an internet connection</li>
<li>have an external webcam or laptop webcam</li>
<li>have an external microphone or laptop microphone</li>
<li>have a photo of valid ID</li>
<li>have pictures of your front, back, left, and right of your own testing environment</li>
<li>No headphones, and smartphones and electronics should be out of reach</li>
</ul>
<p>View the full details <a target="_blank" href="https://www.comptia.org/testing/testing-options/take-online-exam">here</a>.</p>
<h2 id="heading-exam-time">Exam Time</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-308.png" alt="Image" width="600" height="400" loading="lazy">
<em>instagram post of my ever supportive partner</em></p>
<blockquote>
<p>I totally appreciate the support!</p>
</blockquote>
<h3 id="heading-my-experience-with-the-online-test-app">My Experience with the Online Test App</h3>
<ul>
<li>The exam was scheduled 12:15 midnight. This was my intention to avoid any noise in the house. </li>
<li>The proctor can see you through the webcam, and you can't see them.</li>
<li>The online testing app slowed and crashed several times. The proctor said it was due to the high volume of test takers.</li>
</ul>
<h3 id="heading-what-i-felt-during-the-exam">What I felt during the exam</h3>
<p>The first few questions I got in the exam were Performance-Based Questions. It was freaking hard. I really couldn't answer with 100% confidence. I encountered a problem using Linux commands <em>grep</em> and <em>awk</em> with piping to another command. </p>
<p>Another problem was about investigating an SELinux policy violation, which requires you have to inspect each command and their respective output to pinpoint which file or directory needed additional configuration.</p>
<blockquote>
<p>If only I had that professional experience, this would have been much easier.</p>
</blockquote>
<p>As I went through more questions, I really felt so dumb and lost my confidence. I didn't know how to answer the questions about network, system, or user configurations. In the bash scripting portion, I knew I wasn't really good at RegEx (regular expressions). </p>
<blockquote>
<p>I had 30 minutes left in my exam and felt like failing...</p>
</blockquote>
<p>My thoughts of plan B were coming back – I would just take the exam again. This was partly due to my own perspective in life. I always tell people I'm used to failure and I'm fine failing as long as I can be persistent until I reach my goal. </p>
<p>Around the 28-minute mark I was about to call it quits, when I heard another voice in my brain (I'm not crazy I tell you. It's the Jedi Mind trick, read <em><a target="_blank" href="https://www.freecodecamp.org/news/cjn-how-to-teach-yourself-to-learn-again/">How to teach yourself to learn again</a></em>). </p>
<blockquote>
<p>The voice said: "don't think about failure now, use the remaining minutes and do your best!"</p>
</blockquote>
<p>So I used the remaining time to jump around to different questions until I'd covered them all. This time with more focus. I changed almost 80% of my answers and I started to do the following strategies to increase my chances of getting the right answer:</p>
<ul>
<li>Process of elimination - I removed choices that I knew were totally wrong.</li>
<li>I stuck with what I knew - I didn't choose an answer if I didn't know what it meant.</li>
<li>Deeper focus - I read word by word and tried to use both comprehension and logical thinking.</li>
<li>Eyes closed, mind opened - I convinced myself that I'd studied really hard for this exam so it must be stored in my brain somewhere. With that in mind, I tried to retrieve those memories to achieve 100% confidence in some questions that I had around 70% confidence answering.</li>
</ul>
<p>I kept repeating these strategies until the last minute. </p>
<h2 id="heading-exam-results">Exam Results</h2>
<p>The exam ended and I passed – 739 out of 1000! A passing grade point is 720. After 30 minutes, I got an email from CompTIA.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-312.png" alt="Image" width="600" height="400" loading="lazy">
<em>my cool instagram post celebrating my achievement</em></p>
<p>I will still be humbled and say to people that I got lucky. But for myself, I won't say I got lucky because I changed most of my answers using a better mindset and more effective strategies.</p>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<ul>
<li>I should really stop taking these exams when I don't have professional experience yet. Why? I encountered the same kind of difficulty and failed my AWS Developer Certification Exam before (here's the article: <em><a target="_blank" href="https://www.freecodecamp.org/news/cjn-i-failed-my-aws-developer-exam/">I failed my AWS Developer Exam. What now?</a></em>). </li>
<li>In studying, I should've done more assessment early on to focus on my knowledge gap instead of speeding through all the materials.</li>
<li>During the exam, I needed to remind myself this is my reality now. What can I do to be great in this situation? This mindset is something I can apply to my current work as well.</li>
<li>Remember to have study sessions with friends or colleagues, as you'll have the chance to grow your knowledge exponentially.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-284.png" alt="Image" width="600" height="400" loading="lazy">
<em>quote from Gladiator (2000) movie</em></p>
<h2 id="heading-what-now-clark">What now, Clark?</h2>
<p>I rejoined CityU as a full-timer with a position of Program Manager for AWS Apprentice Program (Full Stack Web Systems Developer) last April 20, 2019. </p>
<p>With the Linux+ Certified under my belt, I have gained additional experience, along with my previous experience being a TA Lead with the same program. It's allowed me to better lead, teach, and mentor the new cohort. This includes my team that includes new TAs that I know for sure will be more successful than I was.</p>
<p>I will do my best to keep teaching and mentoring students while sharpening my software development skills, as I'm still on a journey to find a software developer job in the tech industry. I know it's hard coming from a non-tech background to transition, but we'll all get there in time.</p>
<p>To my readers, thank you for reading my article. I really want to focus more on technical articles but I couldn't let a good story slip away.=)</p>
<p>Connect with me in LinkedIn <a target="_blank" href="https://www.linkedin.com/in/clarkngo/">here</a>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/04/image-322.png" alt="Image" width="600" height="400" loading="lazy">
<em>I couldn't decide on my LinkedIn headline lol</em></p>
<p><strong>Article Video Summary and Q&amp;A</strong></p>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/5evBAfJi4l0" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
