Keyboard shortcuts

Press ← or β†’ to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Welcome to My Learning Journal

Hey, I'm Akib πŸ‘‹ β€” a Full Stack Developer & DevOps Engineer.
This is my personal collection of notes, guides, and cheat sheets on various topics in technology.
I use it both as a quick reference and as a way to share knowledge with others.

Λ—ΛΛ‹β˜•ΛŽΛŠΛ—   Connect with me:

Facebook Instagram LinkedIn X

πŸ“š What You'll Find Here

This site is automatically built and deployed from my
NixOS configuration repository using Nix and mdBook.

  • 🐧 Linux β†’ Installation guides, system tools, and server configs.
  • πŸ’Ύ Databases β†’ Notes on MySQL, Postgres, and more.
  • πŸš€ Deployment β†’ Step-by-step guides on deploying applications.
  • πŸ› οΈ Dev Tools β†’ Shell scripts, Git, automation tricks, and configs.

✨ Happy learning!
It’s Mon Oct 20 18:21:28 UTC 2025 β€” a great day to document something new.

MySQL Usage Guide

DATABASE

Creating, using, and managing databases.

-- Create a new database named myDB
CREATE DATABASE myDB; 

-- Switch to the newly created database
USE myDB; 

-- Delete the myDB database
DROP DATABASE myDB; 

-- Set the myDB database to read-only mode
ALTER DATABASE myDB READ ONLY = 1; 

-- Reset the read-only mode of the myDB database
ALTER DATABASE myDB READ ONLY = 0; 

TABLES

Creating and modifying tables to organize data.

-- Create an 'employees' table with specified columns
CREATE TABLE employees(
    employee_id INT,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    hourly_pay DECIMAL(5, 2),
    hire_date DATE
);

-- Retrieve all data from the 'employees' table
SELECT * FROM employees; 

-- Rename the 'employees' table to 'workers'
RENAME TABLE employees TO workers; 

-- Delete the 'employees' table
DROP TABLE employees; 

Altering Tables

-- Add a new column 'phone_number' to the 'employees' table
ALTER TABLE employees
ADD phone_number VARCHAR(15);

-- Rename the 'phone_number' column to 'email'
ALTER TABLE employees
RENAME COLUMN phone_number TO email;

-- Change the data type of the 'email' column
ALTER TABLE employees
MODIFY COLUMN email VARCHAR(100);

-- Change the position of the 'email' column
ALTER TABLE employees
MODIFY email VARCHAR(100) AFTER last_name;

-- Move the 'email' column to the first position
ALTER TABLE employees
MODIFY email VARCHAR(100) FIRST;

-- Delete the 'email' column
ALTER TABLE employees
DROP COLUMN email;

INSERT ROW

Inserting data into tables.

-- Insert a single row into the 'employees' table
INSERT INTO employees VALUES(1, "Akib", "Ahmed", 25.90, "2024-04-06");

-- Insert multiple rows into the 'employees' table
INSERT INTO employees VALUES 
(2, "Sakib", "Ahmed", 20.10, "2024-04-06"),
(3, "Rakib", "Ahmed", 16.40, "2024-04-06"),
(4, "Mula", "Ahmed", 10.90, "2024-04-06"),
(5, "Kodhu", "Ahmed", 19.70, "2024-04-06"),
(6, "Lula", "Ahmed", 23.09, "2024-04-06");

-- Insert specific fields into the 'employees' table
INSERT INTO employees (employee_id, first_name, last_name) VALUES(6, "Munia", "Khatun");

SELECT

Retrieving data from tables.

-- Retrieve all data from the 'employees' table
SELECT * FROM employees;

-- Retrieve specific fields from the 'employees' table
SELECT first_name, last_name FROM employees;

-- Retrieve data from the 'employees' table based on a condition
SELECT * FROM employees WHERE employee_id <= 2;

-- Retrieve data where the 'hire_date' column is NULL
SELECT * FROM employees WHERE hire_date IS NULL;

-- Retrieve data where the 'hire_date' column is not NULL
SELECT * FROM employees WHERE hire_date IS NOT NULL;

UPDATE & DELETE

Modifying and deleting data.

-- Update data in the 'employees' table based on a condition
UPDATE employees
SET hourly_pay = 10.3, hire_date = "2024-01-05"
WHERE employee_id = 7;

-- Update all rows in the 'employees' table for the 'hourly_pay' column
UPDATE employees
SET hourly_pay = 10.3;

-- Delete rows from the 'employees' table where 'hourly_pay' is NULL
DELETE FROM employees
WHERE hourly_pay IS NULL;

-- Delete the 'date_time' column from the 'employees' table
ALTER TABLE employees
DROP COLUMN date_time;

AUTO-COMMIT, COMMIT & ROLLBACK

Managing transactions.

-- Turn off auto-commit mode
SET AUTOCOMMIT = OFF;

-- Manually save changes made in the current transaction
COMMIT;

-- Delete all data from the 'employees' table
DELETE FROM employees;

-- Roll back changes made in the current transaction
ROLLBACK;

DATE & TIME

Working with date and time data.

-- Add a 'join_time' column to the 'employees' table
ALTER TABLE employees
ADD COLUMN join_time TIME;

-- Update the 'join_time' column with the current time
UPDATE employees
SET join_time = CURRENT_TIME();

-- Update the 'hire_date' column based on a condition
UPDATE employees
SET hire_date = CURRENT_DATE() + 1
WHERE hourly_pay >= 20;

-- Add a 'date_time' column to the 'employees' table
ALTER TABLE employees
ADD COLUMN date_time DATETIME;

-- Update the 'date_time' column with the current date and time
UPDATE employees
SET date_time = NOW();

-- Change the name of the 'hire_date' column to 'hire_date'
ALTER TABLE employees
CHANGE COLUMN hire_date hire_date DATE;

CONSTRAINTS

Ensuring data integrity with constraints.

UNIQUE

-- Create a 'products' table with a unique constraint on the 'product_name' column
CREATE TABLE products(
    product_id INT,
    product_name VARCHAR(50) UNIQUE,
    product_price DECIMAL(4,2)
);

-- Add a unique constraint to the 'product_name' column in the 'products' table
ALTER TABLE products
ADD CONSTRAINT UNIQUE(product_name);

-- Insert data into the 'products' table
INSERT INTO products VALUES
(1, "tea", 15.9),
(2, "coffee", 20.89),
(3, "lemon", 10.10);

NOT NULL

-- Create a 'products' table with a NOT NULL constraint on the 'product_price' column
CREATE TABLE products(
    product_id INT,
    product_name VARCHAR(50) UNIQUE,
    product_price DECIMAL(4,2) NOT NULL
);

-- Update the 'product_price' column to be NOT NULL
ALTER TABLE products
MODIFY product_price DECIMAL(4,2) NOT NULL;

-- Insert data into the 'products' table with a NOT NULL column
INSERT INTO products VALUES(4, "mango", 0);

CHECK

-- Create an 'employees' table with a check constraint on the 'hourly_pay' column
CREATE TABLE employees(
    employee_id INT,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    hourly_pay DECIMAL(5, 2),
    hire_date DATE,
    CONSTRAINT chk_hourly_pay CHECK (hourly_pay >= 10)
);

-- Add a check constraint to the 'hourly_pay' column
ALTER TABLE employees
ADD CONSTRAINT chk_hourly_pay CHECK(hourly_pay >= 10);

-- Insert data into the 'employees' table
INSERT INTO employees VALUES(7, "Kutta", "Mizan", 10.0, CURRENT_DATE(), CURRENT_TIME());

DEFAULT

-- Create a 'products' table with a default value for the 'product_price' column
CREATE TABLE products(
    product_id INT,
    product_name VARCHAR(50) UNIQUE,
    product_price DECIMAL(4,2) DEFAULT 0
);

-- Set the default value for the 'product_price' column
ALTER TABLE products
ALTER product_price SET DEFAULT 0;

-- Insert data into the 'products' table with a default value
INSERT INTO products (product_id, product_name) VALUES(5, "soda");

-- Create a 'transactions' table with a default value for the 'transaction_date' column
CREATE TABLE transactions(
    transaction_id INT,
    amount DECIMAL(5,2),
    transaction_date DATETIME DEFAULT NOW()
);

PRIMARY KEY

-- Create a table for transactions with a primary key
CREATE TABLE transactions(
    transaction_id INT PRIMARY KEY,
    amount DECIMAL(4,2),
    transaction_date DATETIME
);

-- Add a primary key constraint
ALTER TABLE transactions
ADD CONSTRAINT PRIMARY KEY(transaction_id);

-- Set auto-increment for the primary key
ALTER TABLE transactions AUTO_INCREMENT = 1000;

-- Insert data into the transactions table
INSERT INTO transactions(amount) VALUES (54.20);

-- Select all data from the transactions table
SELECT * FROM transactions;

AUTO_INCREMENT

-- Create a table for transactions with an auto-increment primary key
CREATE TABLE transactions(
    transaction_id INT PRIMARY KEY AUTO_INCREMENT,
    amount DECIMAL(5,2),
    transaction_date DATETIME DEFAULT NOW()
);

-- Set the default increment level
ALTER TABLE transactions AUTO_INCREMENT = 1000;

-- Insert data into the transactions table, auto-increment starts from 1000
INSERT INTO transactions(amount) VALUES (45.20), (23.40), (98.00), (43.45);

-- Select all data from the transactions table
SELECT * FROM transactions;

FOREIGN KEY

-- Create a table for customers with a primary key
CREATE TABLE customers(
    customer_id INT PRIMARY KEY AUTO_INCREMENT,
    first_name VARCHAR(50),
    last_name VARCHAR(50)
);

-- Create a table for

 transactions with a foreign key constraint
CREATE TABLE transactions(
    transaction_id INT PRIMARY KEY AUTO_INCREMENT,
    amount DECIMAL(5,2),
    transaction_date DATETIME DEFAULT NOW(),
    customer_id INT,
    FOREIGN KEY(customer_id) REFERENCES customers(customer_id)
);

-- Add a foreign key constraint to the transactions table
ALTER TABLE transactions
ADD CONSTRAINT fk_customer_key
FOREIGN KEY(customer_id) REFERENCES customers(customer_id);

-- Insert data into the transactions table with customer_id
INSERT INTO transactions(amount, customer_id) VALUES (34.34, 1), (123.4, 3), (32.32, 1), (12.00, 2);

JOIN

Combining data from multiple tables.

-- Inner join transactions and customers tables
SELECT * 
FROM transactions 
INNER JOIN customers
ON transactions.customer_id = customers.customer_id;

-- Select specific fields from joined tables
SELECT transaction_id, transaction_date, first_name, last_name
FROM transactions 
INNER JOIN customers
ON transactions.customer_id = customers.customer_id;

-- Left join transactions and customers tables
SELECT *
FROM transactions 
LEFT JOIN customers
ON transactions.customer_id = customers.customer_id;

-- Right join transactions and customers tables
SELECT *
FROM transactions 
RIGHT JOIN customers
ON transactions.customer_id = customers.customer_id;

FUNCTIONS

Built-in SQL functions.

-- Count the number of transactions
SELECT COUNT(amount) AS "Transaction count" FROM transactions;

-- Find the maximum amount
SELECT MAX(amount) AS max_dollar FROM transactions;

-- Find the minimum amount
SELECT MIN(amount) AS min_dollar FROM transactions;

-- Find the average amount
SELECT AVG(amount) AS avg_dollar FROM transactions;

-- Calculate the total amount
SELECT SUM(amount) AS sum_of_dollar FROM transactions;

-- Concatenate first_name and last_name into a new column
SELECT CONCAT(first_name, " ", last_name) as full_name FROM customers;

AND, OR & NOT

Combining conditions in SQL queries.

-- Add a job column to the employees table
ALTER TABLE employees
ADD COLUMN job VARCHAR(50) AFTER hourly_pay;

-- Update job data based on employee_id
UPDATE employees
SET job = "Programmer" 
WHERE employee_id = 1;

-- Select employees with specific conditions
SELECT * FROM employees
WHERE employee_id >= 2 AND employee_id <= 6 AND job = "vendor";

-- Select employees with specific conditions using OR
SELECT * FROM employees
WHERE job = "programmer" OR job = "vendor";

-- Select employees with specific conditions using NOT
SELECT * FROM employees
WHERE NOT job = "programmer" AND NOT job = "vendor";

-- Select employees within a certain hourly pay range
SELECT * FROM employees
WHERE hourly_pay BETWEEN 15 AND 26;

-- Select employees with specific jobs using IN
SELECT * FROM employees
WHERE job IN("programmer", "vendor", "doctor");

WILD-CARDS

Using wildcards for pattern matching.

-- Select employees with first name ending with "hu"
SELECT * FROM employees
WHERE first_name LIKE "%hu";

-- Select employees hired on a specific day (07)
SELECT * FROM employees
WHERE hire_date LIKE "____-__-07";

-- Select employees with job ending with "e" followed by another character
SELECT * FROM employees
WHERE job LIKE "%e_";

ORDER BY

Sorting query results.

-- Select employees ordered by hourly pay in ascending order
SELECT * FROM employees
ORDER BY hourly_pay ASC;

-- Select employees ordered by hire date in descending order
SELECT * FROM employees
ORDER BY hire_date DESC;

-- Select transactions ordered by amount in descending order and customer_id in ascending order
SELECT * FROM transactions
ORDER BY amount DESC, customer_id ASC;

LIMIT

Limiting the number of records returned.

-- Select the first 3 customers
SELECT * FROM customers
LIMIT 3;

-- Select the last 3 customers ordered by customer_id
SELECT * FROM customers
ORDER BY customer_id DESC LIMIT 3;

-- Select 2 customers starting from the 1st position (pagination)
SELECT * FROM customers
LIMIT 0,2;

UNION

Combining results from multiple SELECT statements.

-- Combine unique first and last names from employees and customers
SELECT first_name, last_name FROM employees
UNION
SELECT first_name, last_name FROM customers;

-- Combine all first and last names from employees and customers, including duplicates
SELECT first_name, last_name FROM employees
UNION ALL
SELECT first_name, last_name FROM customers;

SELF JOIN

Joining a table to itself.

-- Add a referral_id column to the customers table
ALTER TABLE customers
ADD COLUMN referral_id INT;

-- Update referral_id for customers
UPDATE customers
SET referral_id = 1
WHERE customer_id = 2;

-- Self join to show referred customers
SELECT a.customer_id, a.first_name, a.last_name,
       CONCAT(b.first_name, " ", b.last_name) AS "referred_by"
FROM customers AS a
INNER JOIN customers AS b
ON a.referral_id = b.customer_id;

-- Add a supervisor_id column to the employees table
ALTER TABLE employees
ADD supervisor_id INT;

-- Update supervisor_id for employees
UPDATE employees
SET supervisor_id = 7 
WHERE employee_id BETWEEN 2 and 6;

-- Update supervisor_id for a specific employee
UPDATE employees
SET supervisor_id = 1 
WHERE employee_id = 7;

-- Self join to show employees and their supervisors
SELECT a.employee_id, a.first_name, a.last_name,
       CONCAT(b.first_name, " ", b.last_name) AS "reports to"
FROM employees AS a
INNER JOIN employees AS b
ON a.supervisor_id = b.employee_id;

VIEWS

Creating and using virtual tables.

-- Create a view based on the employees table
CREATE VIEW employee_attendance AS
SELECT first_name, last_name
FROM employees;

-- Retrieve data from the view
SELECT * FROM employee_attendance
ORDER BY last_name ASC;

-- Create a view for customer emails
CREATE VIEW customer_emails AS
SELECT email
FROM customers;

-- Insert data into the customers table and view the changes in the view
INSERT INTO customers
VALUES(6, "Musa", "Rahman", NULL, "musa@mail.com");
SELECT * FROM customers;
SELECT * FROM customer_emails;

INDEX

Improving query performance with indexes.

-- Show indexes for the customers table
SHOW INDEXES FROM customers;

-- Create an index on the last_name column
CREATE INDEX last_name_index
ON customers(last_name);

-- Use the index to speed up search
SELECT * FROM customers
WHERE last_name = "Chan";

-- Create a multi-column index
CREATE INDEX last_name_first_name_idx
ON customers(last_name, first_name);

-- Drop an index
ALTER TABLE customers
DROP INDEX last_name_index;

-- Benefit from the multi-column index during search
SELECT * FROM customers
WHERE last_name = "Chan" AND first_name = "Kuki";

SUB-QUERY

Using sub-queries to nest queries within queries.

-- Get the average hourly pay
SELECT AVG(hourly_pay) FROM employees;

-- Use a sub-query to get the average hourly pay within a larger query
SELECT first_name, last_name, hourly_pay,
       (SELECT AVG(hourly_pay) FROM employees) AS avg_hourly_pay
FROM employees;

-- Filter rows based on a sub-query result
SELECT first_name, last_name, hourly_pay 
FROM employees
WHERE hourly_pay >= (SELECT AVG(hourly_pay) FROM employees);

-- Use a sub-query with IN to filter customers
SELECT first_name, last_name
FROM customers
WHERE customer_id IN (SELECT DISTINCT customer_id
                      FROM transactions
                      WHERE customer_id IS NOT NULL);

-- Use a sub-query with NOT IN to filter customers
SELECT first_name, last_name
FROM customers
WHERE customer_id NOT IN (SELECT DISTINCT customer_id
                          FROM transactions
                          WHERE customer_id IS NOT NULL);

GROUP BY

Aggregating data with grouping.

-- Sum amounts grouped by transaction date
SELECT SUM(amount), transaction_date
FROM transactions
GROUP BY transaction_date;

-- Get the maximum amount per customer
SELECT MAX(amount), customer_id
FROM transactions
GROUP BY customer_id;

-- Count transactions per customer having more than one transaction
SELECT COUNT(amount), customer_id
FROM transactions
GROUP BY customer_id
HAVING COUNT(amount) > 1 AND customer_id IS NOT NULL;

ROLL-UP

Extending group by with roll-up for super-aggregate values.

-- Sum amounts with a roll-up
SELECT SUM(amount), transaction_date
FROM transactions
GROUP BY transaction_date WITH ROLLUP;

-- Count transactions with a roll-up
SELECT COUNT(transaction_id) AS "# of orders", customer_id
FROM transactions 
GROUP BY customer_id WITH ROLLUP;

-- Sum hourly pay with a roll-up
SELECT SUM(hourly_pay) AS "hourly pay", employee_id
FROM employees
GROUP BY employee_id WITH ROLLUP;

ON-DELETE

Handling foreign key deletions.

-- Delete a customer record
DELETE FROM customers
WHERE customer_id = 3;

-- Disable foreign key checks and delete a customer
SET foreign_key_checks = 0;
DELETE FROM customers
WHERE customer_id = 3;
SET foreign_key_checks = 1;

-- Insert a customer record
INSERT INTO customers
VALUES(3, "Shilpi", "Akter", 3, "shilpy@mail.com");

-- Create a table with ON DELETE SET NULL
CREATE TABLE transactions(
    transaction_id INT PRIMARY KEY,
    amount DECIMAL(5,

3),
    customer_id INT,
    order_date DATE,
    FOREIGN KEY(customer_id) REFERENCES customers(customer_id)
    ON DELETE SET NULL
);

-- Update an existing table with ON DELETE SET NULL
ALTER TABLE transactions 
DROP FOREIGN KEY fk_customer_key;
ALTER TABLE transactions 
ADD CONSTRAINT fk_customer_key
FOREIGN KEY(customer_id) REFERENCES customers(customer_id)
ON DELETE SET NULL;

-- Create or alter a table with ON DELETE CASCADE
ALTER TABLE transactions
ADD CONSTRAINT fk_transaction_id
FOREIGN KEY(customer_id) REFERENCES customers(customer_id)
ON DELETE CASCADE;

STORED PROCEDURE

Creating reusable SQL code blocks.

-- Create a procedure
DELIMITER $$
CREATE PROCEDURE get_customers()
BEGIN
    SELECT * FROM customers;
END $$
DELIMITER ;

-- Delete a procedure
DROP PROCEDURE get_customers;

-- Create a procedure with an argument
DELIMITER $$
CREATE PROCEDURE find_customer(IN id INT)
BEGIN
    SELECT * FROM customers WHERE customer_id = id;
END $$
DELIMITER ;

-- Create a procedure with multiple arguments
DELIMITER $$
CREATE PROCEDURE find_customer(IN f_name VARCHAR(50), IN l_name VARCHAR(50))
BEGIN 
    SELECT * FROM customers WHERE first_name = f_name AND last_name = l_name;
END $$
DELIMITER ;

-- Call a procedure
CALL find_customer("Akib", "Ahmed");

TRIGGERS

Automatically performing actions in response to events.

-- Add a salary column to the employees table
ALTER TABLE employees
ADD COLUMN salary DECIMAL(10,2) AFTER hourly_pay;

-- Calculate salary based on hourly pay
UPDATE employees
SET salary = hourly_pay * 2080;

-- Create a trigger to update salary before updating hourly pay
CREATE TRIGGER before_hourly_pay_update
BEFORE UPDATE ON employees
FOR EACH ROW
SET NEW.salary = (NEW.hourly_pay * 2080);

-- Update hourly pay and see the trigger in action
UPDATE employees 
SET hourly_pay = 50
WHERE employee_id = 1;

-- Create a trigger to update salary before inserting a new employee
CREATE TRIGGER before_hourly_pay_insert
BEFORE INSERT ON employees
FOR EACH ROW
SET NEW.salary = (NEW.hourly_pay * 2080);

-- Insert a new employee and see the trigger in action
INSERT INTO employees
VALUES(6, "Shel", "Plankton", 10, NULL, "Janitor", "2024-06-17", "09:22:23", 7);

-- Create a table for expenses
CREATE TABLE expenses(
    expense_id INT PRIMARY KEY,
    expense_name VARCHAR(50),
    expense_total DECIMAL(10,2)
);

-- Insert initial data into the expenses table
INSERT INTO expenses
VALUES (1, "salaries", 0), (2, "supplies", 0), (3, "taxes", 0);

-- Update expenses based on salaries
UPDATE expenses 
SET expense_total = (SELECT SUM(salary) FROM employees)
WHERE expense_name = "salaries";

-- Create a trigger to update expenses after deleting an employee
CREATE TRIGGER after_salary_delete
AFTER DELETE ON employees
FOR EACH ROW
UPDATE expenses
SET expense_total = expense_total - OLD.salary
WHERE expense_name = "salaries";

-- Delete an employee and see the trigger in action
DELETE FROM employees
WHERE employee_id = 6;

-- Create a trigger to update expenses after inserting a new employee
CREATE TRIGGER after_salary_insert
AFTER INSERT ON employees
FOR EACH ROW
UPDATE expenses
SET expense_total = expense_total + NEW.salary
WHERE expense_name = "salaries";

-- Insert a new employee and see the trigger in action
INSERT INTO employees
VALUES(6, "Shel", "Plankton", 10, NULL, "Janitor", "2024-06-17", "09:22:23", 7);

-- Create a trigger to update expenses after updating an employee's salary
CREATE TRIGGER after_salary_update
AFTER UPDATE ON employees
FOR EACH ROW
UPDATE expenses
SET expense_total = expense_total + (NEW.salary - OLD.salary)
WHERE expense_name = "salaries";

-- Update an employee's hourly pay and see the trigger in action
UPDATE employees
SET hourly_pay = 100
WHERE employee_id = 1;

Linux Server Setup & MERN App Deployment

These are the steps to setup an Ubuntu server from scratch and deploy a MERN app with the PM2 process manager and Nginx. We are using Linode, but you could just as well use a different cloud provider or your own machine or VM.

Create an account at Linode

Click on Create Linode

Choose your server options (OS, region, etc)

SSH Keys

You will see on the setup page an area to add an SSH key.

There are a few ways that you can log into your server. You can use passwords, however, if you want to be more secure, I would suggest setting up SSH keys and then disabling passwords. That way you can only log in to your server from a PC that has the correct keys setup.

I am going to show you how to setup authentication with SSH, but if you want to just use a password, you can skip most of this stuff.

You need to generate an SSH key on your local machine to login to your server remotely. Open your terminal and type

ssh-keygen

By default, it will create your public and private key files in the .ssh directory on your local machine and name them id_rsa and id_rsa.pub. You can change this if you want, just make sure when it asks, you put the entire path to the key as well as the filename. I am using id_rsa_linode

Once you do that, you need to copy the public key. You can use the cat command and then copy the key

cat ~/.ssh/id_rsa_linode.pub

Copy the key. It will look something like this:

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDEwMkP0KHX19q2dM/9pB9dpB2B/FwdeP4egXCgdEOraJuqGvaylKgbu7XDFinP6ByqJQg/w8vRV0CsFXrnr+Lh51fKv8ZPvV/yRIMjxKzNn/0+asatkjrkOwT3f3ipbzfS0bsqfWTHivZ7UNMrOHaaSezxvJpPGbW3aoTCFSA/sUUUSiWZ65v7I/tFkXE0XH+kSDFbLUDDNS1EzofWZFRcdSFbC3zrGsQHN3jcit6ba7bACQYixxFCgVB0mZO9SOgFHC64PEnZh5hJ8h8AqIjf5hDF9qFdz2jFEe/4aQmKQAD3xAPKTXDLLngV/2yFF0iWpnJ9MZ/mJoLVzhY2pfkKgnt/SUe/Hn1+jhX4wrz7wTDV4xAe35pmnajFjDppJApty+JOzKf3ifr4lNeZ5A99t9Pu0294BhYxm7/mKXiWPsevX9oSZxSJmQUtqWWz/KBVoVjlTRgAgLYbKCNBzmw7+qdRxoxxscQCQrCpJMlat56vxK8cjqiESvduUu78HHE= trave@ASUS

Now paste that into the Linode.com textarea and name it (eg.My PC)

At some point, you will be asked to enter a root password for your server as well.

Connecting as Root

Finish the setup and then you will be taken to your dashboard. The status will probably say Provisioning. Wait until it says Running and then open your local machine's terminal and connect as root. Of course you want to use your own server's IP address

ssh root@69.164.222.31

At this point, passwords are enabled, so you will be asked for your root password.

If you authenticate and login, you should see a welcome message and your prompt should now say root@localhost:~#. This is your remote server

I usually suggest updating and upgrading your packages

sudo apt update
sudo apt upgrade

Create a new user

Right now you are logged in as root and it is a good idea to create a new account. Using the root account can be a security risk.

You can check your current user with the command:

whoami

It will say root right noe.

Let's add a new user. I am going to call my user brad

adduser brad

Just hit enter through all the questions. You will be asked for a use password as well.

You can use the following command to see the user info including the groups it belongs to

id brad

Now, let's add this user to the "sudo" group, which will give them root privileges.

usermod -aG sudo brad

Now if you run the following command, you should see sudo

id brad

Add SSH keys for new account

If you are using SSH, you will want to setup SSH keys for the new account. We do this by adding it to a file called authorized_keys in the users directory.

Go to the new users home directory

cd /home/brad

Create a .ssh directory and go into it

mkdir .ssh
cd .ssh

Create a new file called authorized_keys

touch authorized_keys

Now you want to put your public key in that file. You can open it with a simpl text editor called nano

sudo nano authorized_keys

Now you can paste your key in here. Just repeat the step above where we ran cat and then the location of your public key. IMPORTANT: Make sure you open a new terminal for this that is not logged into your server.

Now paste the key in the file and hi ctrl or cmd+X then hit Y to save and hit enter again

Disabling passwords

This is an extra security step. Like I said earlier, we can disable passwords so that only your local machine with the correct SSH keys can login.

Open the following file on your server

sudo nano /etc/ssh/sshd_config

Look for where it says

PasswordAuthentication Yes

Remove the # if there is one and change the Yes to No

If you want to disable root login all together you could change permitRootLogin to no as well. Be sure to remove the # sign becayse that comments the line out.

Save the file by exiting (ctrl+x) and hit Y to save.

Now you need to reset the sshd service

sudo systemctl restart sshd

Now you can logout by just typing logout

Try logging back in with your user (Use your username and server's IP)

ssh brad@69.164.222.31

If you get a message that says "Publick key denied" or something like that, run the following commands:

eval `ssh-agent -s`
ssh-add ~/.ssh/id_rsa_linode     # replace this with whatever you called your key file

try logging in again and you should see the welcome message and not have to type in any password.

Node.js setup

Now that we have provisioned our server and we have a user setup with SSH keys, it's time to start setting up our app environment. Let's start by installing Node.js

We can install Node.js with curl using the following commands

curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# Check to see if node was installed
node --version
npm --version

Get files on the server

We want to get our application files onto the server. We will use Git for this. I am using the goal setter app from my MERN stack series on YouTube

On your SERVER, go to where you want the app to live and clone the repo you want to deply from GitHub (or where ever else)

Here is the repo I will be using. Feel free to deploy the same app: https://github.com/bradtraversy/mern-tutorial

mkdir sites
cd sites
git clone https://github.com/bradtraversy/mern-tutorial.git

Now I should have a folder called mern-tutorial with all of my files and folders.

App setup

There are a few things that we need to do including setting up the .ENV file, installing dependencies and building our static assets for React.

.env file

With this particular application, I create a .envexample file because I did not want to push the actual .env file to GitHub. So you need to first rename that .envexample:

mv .envexample .env

# To check
ls -a

Now we need to edit that file

sudo nano .env

Change the NODE_ENV to "production" and change the MONGO_URI to your own. You can create a mongodb Atlas database here

Exit with saving.

Dependencies & Build

We need to install the server dependencies. This should be run from the root of the mern-tutorial folder. NOT the backend folder.

npm install

Install frontend deps:

cd frontend
npm install

We need to build our static assets as well. Do this from the frontend folder

npm run build

Run the app

Now we should be able to run the app like we do on our local machine. Go into the root and run

npm start

If you go to your ip and port 5000, you should see your app. In my case, I would go to

http://69.164.222.31:5000

Even though we see our app running, we are not done. We don't want to leave a terminal open with npm start. We also don't want to have to go to port 5000. So let's fix that.

Stop the app from running with ctrl+C

PM2 Setup

PM2 is a production process manager fro Node.js. It allows us to keep Node apps running without having to have terminal open with npm start, etc like we do for development.

Let's first install PM2 globally with NPM

sudo npm install -g pm2

Run with PM2

pm2 start backend/server.js   # or whatever your entry file is

Now if you go back to your server IP and port 5000, you will see it running. You could even close your terminal and it will still be running

There are other pm2 commands for various tasks as well that are pretty self explanatory:

  • pm2 show app
  • pm2 status
  • pm2 restart app
  • pm2 stop app
  • pm2 logs (Show log stream)
  • pm2 flush (Clear logs)

Firewall Setup

Obviously we don't want users to have to enter a port of 5000 or anything else. We are going to solve that by using a server called NGINX. Before we set that up, lets setup a firewall so that people can not directly access any port except ports for ssh, http and https

The firewall we are using is called UFW. Let's enable it.

  sudo ufw enable

You will notice now if you go to the site using :5000, it will not work. That is because we setup a firewall to block all ports.

You can check the status of the firewall with

sudo ufw status

Now let's open the ports that we need which are 22, 80 and 443

sudo ufw allow ssh (Port 22)
sudo ufw allow http (Port 80)
sudo ufw allow https (Port 443)

Setup NGINX

Now we need to install NGINX to serve our app on port 80, which is the http port

sudo apt install nginx

If you visit your IP address with no port number, you will see a Welcome to nginx! page.

Now we need to configure a proxy for our MERN app.

Open the following config file

sudo nano /etc/nginx/sites-available/default

Find the location / area and replace with this

location / {
        proxy_pass http://localhost:5000;    # or which other port your app runs on
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }

Above that, you can also put the domain that you plan on using:

server_name yourdomain.com www.yourdomain.com;

Save and close the file

You can check your nginx configuration with the following command

sudo nginx -t

Now restart the NGINX service:

sudo service nginx restart

Now you should see your app when you go to your IP address in the browser.

Domain Name

You probably don't want to use your IP address to access your app in the browser. So let's go over setting your domain with a Linode.

You need to register your domain. It doesn't matter who you use for a registrar. I use Namecheap, but you could use Godaddy, Google Domains or anyone else.

You need to change the nameservers with your Domain registrar. The process can vary depending on who you use. With Namecheap, the option is right on the details page.

You want to add the following nameservers:

  • ns1.linode.com
  • ns2.linode.com
  • ns3.linode.com
  • ns4.linode.com
  • ns5.linode.com

Technically this could take up to 48 hours, but it almost never takes that long. In my own experience, it is usually 30 - 90 minutes.

Set your domain in Linode

Go to your dashboard and select Domains and then Create Domain

Add in your domain name and link to the Linode with your app, then submit the form.

Now you will see some info like SOA Record, NS Record, MX Record, etc. There are A records already added that link to your IP address, so you don't have to worry about that. If you wanted to add a subdomain, you could create an A record here for that.

Like I said, it may take a few hours, but you should be all set. You have now deployed your application.

if you want to make changes to your app, just push to github and run a git pull on your server. There are other tools to help automate your deployments, but I will go over that another time.

Set Up SSL

You can purchase an SSL and set it with your domain registrar or you can use Let's Encrypt and set one up for free using the following commands:

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

# Only valid for 90 days, test the renewal process with
certbot renew --dry-run

NixOS with LUKS, LVM, and Btrfs: A Comprehensive Guide

This guide covers the installation and management of a NixOS system using a full-disk encryption setup with LUKS, LVM for volume management, and Btrfs for the filesystem.

1. πŸ’Ώ NixOS Installation: Manual Partitioning with LUKS + LVM + Btrfs

This section guides you through a fresh installation of NixOS on a single disk.

Prerequisites

  1. Boot the NixOS installer.
  2. Connect to the internet.
  3. Switch to a root shell: sudo -i.
  4. Identify your target disk: lsblk.
  5. Set a variable for your device:
    export DEVICE=/dev/sda
    

Step 1. Wipe Disk and Create Partition Table

🚨 Warning: This will destroy all data on the specified disk.

sgdisk --zap-all ${DEVICE}

Step 2. Create Partitions

We will create a standard 4-partition layout for a modern UEFI system.

# Partition 1: 1M BIOS Boot partition (for GRUB compatibility)
sgdisk --new=1:0:+1M --typecode=1:EF02 --change-name=1:boot ${DEVICE}

# Partition 2: 500M EFI System Partition (ESP)
sgdisk --new=2:0:+500M --typecode=2:EF00 --change-name=2:ESP ${DEVICE}

# Partition 3: 4G Swap partition
sgdisk --new=3:0:+4G --typecode=3:8200 --change-name=3:swap ${DEVICE}

# Partition 4: The rest of the disk for our encrypted data
# We use 8E00 which is the typecode for "Linux LVM"
sgdisk --new=4:0:0 --typecode=4:8E00 --change-name=4:root ${DEVICE}

Step 3. Format Unencrypted Filesystems

Format the ESP and swap partitions, giving them labels for easy mounting.

# Format the EFI partition
mkfs.vfat -n ESP ${DEVICE}p2

# Set up the swap partition
mkswap -L swap ${DEVICE}p3

Step 4. Set Up LUKS Encryption and LVM πŸ”’

This is the core of the setup. We create an encrypted container on our main partition and then build an LVM structure inside it.

# 1. Create the LUKS encrypted container on the fourth partition.
# You will be prompted to enter and confirm a strong passphrase. Remember this!
echo "Formatting the LUKS container. Please enter your encryption passphrase."
cryptsetup luksFormat --label crypted ${DEVICE}p4

# 2. Open the LUKS container to make it accessible.
# This creates a decrypted "virtual" device at /dev/mapper/crypted.
echo "Opening the LUKS container. Please enter your passphrase."
cryptsetup open ${DEVICE}p4 crypted

# 3. Set up LVM *inside* the decrypted container.
# Initialize the physical volume (PV) on the decrypted device
pvcreate /dev/mapper/crypted

# Create the volume group (VG) named "root_vg"
vgcreate root_vg /dev/mapper/crypted

# Create the logical volume (LV) named "root" that uses all available space
lvcreate -l 100%FREE -n root root_vg

Step 5. Format the LVM Volume with Btrfs

Now, we format the LVM logical volume (not the physical partition) with Btrfs.

mkfs.btrfs -L root /dev/root_vg/root

Step 6. Create and Mount Btrfs Subvolumes

We use Btrfs subvolumes to separate parts of our system, which is standard practice for NixOS.

# 1. Mount the top-level Btrfs volume
mount /dev/root_vg/root /mnt

# 2. Create the subvolumes
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/persist
btrfs subvolume create /mnt/nix

# 3. Unmount the top-level volume
umount /mnt

# 4. Mount the root subvolume with correct options
mount -o subvol=root,compress=zstd,noatime /dev/root_vg/root /mnt

# 5. Create the directories for the other mountpoints
mkdir -p /mnt/persist
mkdir -p /mnt/nix
mkdir -p /mnt/boot

# 6. Mount the other subvolumes
mount -o subvol=persist,noatime,compress=zstd /dev/root_vg/root /mnt/persist
mount -o subvol=nix,noatime,compress=zstd /dev/root_vg/root /mnt/nix

Step 7. Mount Boot Partition and Activate Swap

Finish by mounting the ESP and activating the swap.

# Mount the boot partition
mount ${DEVICE}p2 /mnt/boot

# Activate the swap partition
swapon ${DEVICE}p3

Step 8. Generate NixOS Configuration

Finally, generate the NixOS configuration. The installer will automatically detect the LUKS and LVM setup.

nixos-generate-config --root /mnt

Your /mnt/etc/nixos/hardware-configuration.nix will be auto-generated with the correct LUKS and filesystem entries, similar to this:

# Example /etc/nixos/hardware-configuration.nix

{ config, lib, pkgs, modulesPath, ... }:

{
  imports =
    [ (modulesPath + "/profiles/qemu-guest.nix")
    ];

  boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "sr_mod" "virtio_blk" ];
  boot.initrd.kernelModules = [ "dm-snapshot" ];
  boot.kernelModules = [ "kvm-intel" ];
  boot.extraModulePackages = [ ];

  # This part is automatically added to unlock your disk at boot
  boot.initrd.luks = {
    devices."crypted" = {
      device = "/dev/disk/by-label/crypted";
      preLVM = true;
    };
  };

  # These are your Btrfs subvolumes
  fileSystems."/" =
    { device = "/dev/mapper/root_vg-root";
      fsType = "btrfs";
      options = [ "subvol=root" ];
    };

  fileSystems."/persist" =
    { device = "/dev/mapper/root_vg-root";
      fsType = "btrfs";
      options = [ "subvol=persist" ];
    };

  fileSystems."/nix" =
    { device = "/dev/mapper/root_vg-root";
      fsType = "btrfs";
      options = [ "subvol=nix" ];
    };

  # Your boot and swap partitions
  fileSystems."/boot" = {
      device = "/dev/disk/by-label/ESP";
      fsType = "vfat";
      options = [ "fmask=0022" "dmask=0022" ];
    };

  swapDevices =[ { device = "/dev/disk/by-label/swap"; } ];

  nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

You can now proceed with editing your configuration.nix and running nixos-install.


2. βž• Extending an Encrypted LVM Volume with a New Disk

Use this guide when you've added a new physical disk (e.g., /dev/vdb) and want to add its encrypted space to your existing root_vg.

🚨 Pre-flight Check: Backup

Before you begin, ensure you have a backup of any critical data.

Step 1. Partition and Label the New Disk

We'll create a single partition on the new disk (/dev/vdb) and give it a partition label for easy identification.

# Open parted for /dev/vdb
sudo parted /dev/vdb

# Inside parted, run the following commands:
# (parted)
mklabel gpt
mkpart primary 0% 100%
name 1 crypted_ext
quit

This creates /dev/vdb1 and sets its partition name (label) to crypted_ext.

Step 2. Create and Open the LUKS Encrypted Container

Now, encrypt the new partition.

# Encrypt /dev/vdb1.
# -> IMPORTANT: Use the EXACT SAME password as your main encryption.
# -> This allows NixOS to unlock both with a single password prompt.
sudo cryptsetup luksFormat /dev/vdb1

# Open the new LUKS container so we can work with it.
sudo cryptsetup luksOpen /dev/vdb1 crypted_ext_mapper

The unlocked device is now available at /dev/mapper/crypted_ext_mapper.

Step 3. Integrate the New Encrypted Disk into LVM

Add the newly decrypted device as a Physical Volume (PV) to your existing Volume Group (VG).

# 1. Create a new Physical Volume (PV) on the unlocked container.
sudo pvcreate /dev/mapper/crypted_ext_mapper

# 2. Extend your existing 'root_vg' Volume Group with this new PV.
sudo vgextend root_vg /dev/mapper/crypted_ext_mapper

# 3. (Verification) Check your Volume Group. It should now be larger.
sudo vgs

Step 4. Extend the Logical Volume and Btrfs Filesystem

Make the new space available to your filesystem.

# 1. Extend the Logical Volume to use 100% of the new free space.
sudo lvextend -l +100%FREE /dev/mapper/root_vg-root

# 2. Resize the Btrfs filesystem to fill the newly expanded Logical Volume.
sudo btrfs filesystem resize max /

# 3. (Verification) Check your disk space.
df -h /

Step 5. Update configuration.nix

This is the most critical step. You must tell NixOS to unlock this second device at boot.

Edit your /etc/nixos/configuration.nix file and add the new device to boot.initrd.luks.

# Your configuration.nix

boot.initrd.luks = {
  devices."crypted" = {
    device = "/dev/disk/by-label/crypted"; # This is your original /dev/vda4
    preLVM = true;
  };

  # --- ADD THIS NEW BLOCK ---
  devices."crypted_ext" = {
    # Use the partition label you set in Step 1
    device = "/dev/disk/by-partlabel/crypted_ext";
    preLVM = true;
    allowDiscards = true; # Good practice for SSDs/VMs
  };
};

Note on Passwords: Because you used the same password for both LUKS devices, NixOS will ask for your password only once at boot and use it to unlock both containers.

Step 6. Rebuild and Reboot

DO NOT REBOOT until you have applied the new configuration.

# Apply your new NixOS configuration
sudo nixos-rebuild switch

# Now it is safe to reboot
sudo reboot

3. βž– Removing an Encrypted Disk from an LVM Volume

This guide covers the complex process of removing a disk (e.g., /dev/vdb) from a Volume Group when your filesystem spans multiple disks.

🚨 WARNING: This is a high-risk operation. A mistake can lead to total data loss. Back up all critical data before proceeding. This process almost always requires booting from a Live Linux ISO because you cannot shrink a mounted root filesystem.

The Goal

Our goal is to move all data off /dev/vdb (which is part of root_vg) onto your other disk (/dev/mapper/crypted) and then remove /dev/vdb from the LVM setup.

The Problem

You cannot pvmove data off /dev/vdb because there is no free space on the other disk to move it to. You must first shrink your filesystem and logical volume to be smaller than the size of the disk you want to keep.

Example:

  • Disk 1 (/dev/mapper/crypted): 35G
  • Disk 2 (/dev/vdb): 20G
  • Total root_vg size: 55G
  • Your Goal: You must shrink your Btrfs filesystem and LV to < 35G (e.g., 34G).

Step 1. Boot from a Live Linux ISO

  1. Attach a NixOS, Ubuntu, or other Linux ISO to your VM or machine and boot from it.
  2. Open a terminal.

Step 2. Unlock Encrypted Disks and Activate LVM

# 1. Unlock your *main* encrypted partition (the one you are keeping)
# Replace /dev/vda4 with your actual partition
sudo cryptsetup luksOpen /dev/vda4 crypted

# 2. Unlock the *second* disk's encrypted partition
# (This assumes /dev/vdb is encrypted, following the guide in section 2)
sudo cryptsetup luksOpen /dev/vdb1 crypted_ext

# 3. Activate the LVM Volume Group
sudo vgchange -ay

Step 3. Resize Btrfs and LV (Offline)

This is the most critical part.

# 1. Run a filesystem check (highly recommended)
sudo btrfs check /dev/mapper/root_vg-root

# 2. Shrink the Btrfs filesystem.
# We set it to 34G, which is smaller than our 35G target disk.
sudo btrfs filesystem resize 34G /dev/mapper/root_vg-root

# 3. Shrink the Logical Volume to match.
sudo lvreduce -L 34G /dev/mapper/root_vg-root

Step 4. Reboot into Your Normal System

The offline part is done.

sudo reboot

Remove the Live ISO and boot back into your NixOS. Your system will boot up on a smaller filesystem.

Step 5. Migrate Data and Remove the Disk (Online)

Now that you are back in your system, sudo vgs should show free space in root_vg.

# 1. Load the 'dm-mirror' module, which pvmove needs
sudo modprobe dm_mirror

# 2. Move all data extents off the disk you want to remove.
# This will move data from crypted_ext to the free space on crypted.
sudo pvmove -v /dev/mapper/crypted_ext_mapper

# 3. Remove the now-empty Physical Volume from the Volume Group.
sudo vgreduce root_vg /dev/mapper/crypted_ext_mapper

# 4. Remove the LVM metadata from the device.
sudo pvremove /dev/mapper/crypted_ext_mapper

Step 6. Update configuration.nix and Clean Up

  1. Edit your /etc/nixos/configuration.nix and remove the entry for crypted_ext from boot.initrd.luks.
  2. Rebuild your system:
    sudo nixos-rebuild switch
    
  3. You can now safely close the LUKS container and reboot. The disk /dev/vdb is completely free.
    sudo cryptsetup luksClose crypted_ext_mapper
    sudo reboot
    

4. πŸ“š LUKS Command Reference

Common cryptsetup commands for managing LUKS devices.

  • Format a new LUKS container:

    # --label is recommended for use in /dev/disk/by-label/
    cryptsetup luksFormat --label crypted /dev/sda4
    
  • Open (decrypt) a container:

    # This creates a device at /dev/mapper/my_decrypted_volume
    cryptsetup luksOpen /dev/sda4 my_decrypted_volume
    
  • Close (lock) a container:

    cryptsetup luksClose my_decrypted_volume
    
  • Add a new password (key slot):

    # You will be prompted for an *existing* password first.
    cryptsetup luksAddKey /dev/sda4
    
  • Remove a password:

    # You will be prompted for the password you wish to remove.
    cryptsetup luksRemoveKey /dev/sda4
    
  • View header information (and key slots):

    cryptsetup luksDump /dev/sda4
    
  • Resize an online LUKS container: (Useful if you resize the underlying partition).

    cryptsetup resize my_decrypted_volume
    

5. πŸ“š LVM Command Reference

Common commands for managing LVM.

Physical Volume (PV) - The Disks

  • Initialize a disk for LVM:

    pvcreate /dev/mapper/crypted
    
  • List physical volumes:

    pvs
    pvdisplay
    
  • Move data from one PV to another (within the same VG):

    # Moves all data *off* /dev/sdb1
    pvmove /dev/sdb1
    
    # Moves data from /dev/sdb1 *to* /dev/sdc1
    pvmove /dev/sdb1 /dev/sdc1
    
  • Remove LVM metadata from a disk:

    # Only run this *after* removing the PV from its VG.
    pvremove /dev/sdb1
    

Volume Group (VG) - The Pool of Disks

  • Create a new VG:
    # Creates a VG named "my_vg" using two disks
    vgcreate my_vg /dev/sdb1 /dev/sdc1
    
  • List volume groups:
    vgs
    vgdisplay
    
  • Add a disk (PV) to an existing VG:
    vgextend my_vg /dev/sdd1
    
  • Remove a disk (PV) from a VG:
    # The PV must be empty (use pvmove first).
    vgreduce my_vg /dev/sdb1
    
  • Remove a VG:
    # Make sure all LVs are removed first.
    vgremove my_vg
    

Logical Volume (LV) - The "Partitions"

  • Create a new LV:

    # Create a 50G LV named "my_lv" from the "my_vg" pool
    lvcreate -L 50G -n my_lv my_vg
    
    # Create an LV using all remaining free space
    lvcreate -l 100%FREE -n my_other_lv my_vg
    
  • List logical volumes:

    lvs
    lvdisplay
    
  • Extend an LV (and its filesystem):

    # Extend the LV to be 100G in total
    lvresize -L 100G /dev/my_vg/my_lv
    
    # Add 20G to the LV's current size
    lvresize -L +20G /dev/my_vg/my_lv
    
    # Extend the LV to use all free space in the VG
    lvextend -l +100%FREE /dev/my_vg/my_lv
    
    # --- IMPORTANT ---
    # After extending, you must resize the filesystem inside it.
    # For ext4:
    resize2fs /dev/my_vg/my_lv
    # For btrfs:
    btrfs filesystem resize max /path/to/mountpoint
    
  • Reduce an LV (and its filesystem): 🚨 DANGEROUS! You must shrink the filesystem first.

    # 1. Shrink the filesystem (e.g., ext4, UNMOUNTED)
    resize2fs /dev/my_vg/my_lv 40G
    
    # 2. Shrink the LV to match
    lvreduce -L 40G /dev/my_vg/my_lv
    
    # For Btrfs, you can often do it online:
    # 1. Shrink Btrfs
    btrfs filesystem resize 40G /path/to/mountpoint
    # 2. Shrink LV
    lvreduce -L 40G /dev/my_vg/my_lv
    
  • Remove an LV:

    # Make sure it's unmounted first.
    lvremove /dev/my_vg/my_lv
    

6. πŸ“š Btrfs Command Reference

Common commands for managing Btrfs filesystems and subvolumes.

  • Format a device:

    # -L sets the label
    mkfs.btrfs -L root /dev/my_vg/my_lv
    
  • Resize a filesystem:

    # Grow to fill the maximum available space (after an lvextend)
    btrfs filesystem resize max /path/to/mountpoint
    
    # Set to a specific size (e.g., 50G)
    btrfs filesystem resize 50G /path/to/mountpoint
    
    # Shrink by 10G
    btrfs filesystem resize -10G /path/to/mountpoint
    
  • Show filesystem usage:

    # Btrfs-aware 'df'
    btrfs filesystem df /path/to/mountpoint
    
  • Create a subvolume:

    # Mount the top-level (ID 5) volume first
    mount /dev/my_vg/my_lv /mnt
    
    # Create subvolumes
    btrfs subvolume create /mnt/root
    btrfs subvolume create /mnt/nix
    
    umount /mnt
    
  • List subvolumes:

    btrfs subvolume list /path/to/mountpoint
    
  • Delete a subvolume:

    # Deleting a subvolume is recursive and instant
    btrfs subvolume delete /mnt/nix
    
  • Create a snapshot:

    # Create a read-only snapshot of 'root'
    btrfs subvolume snapshot -r /mnt/root /mnt/root-snapshot
    
    # Create a writable snapshot (a clone)
    btrfs subvolume snapshot /mnt/root /mnt/root-clone
    
  • Check a Btrfs filesystem (unmounted):

    btrfs check /dev/my_vg/my_lv
    

NixOS Command Cheatsheet

A collection of useful Nix and NixOS commands for system management.


System & Store Maintenance

  • Verify & Repair Store: Checks the integrity of the Nix store and repairs any issues. Use this if you suspect corruption.

    sudo nix-store --repair --verify --check-contents
    
  • Garbage Collection: Removes all unused packages from the Nix store to free up space.

    sudo nix-collect-garbage -d
    sudo nix-collect-garbage --delete-older-than 7d
    sudo nix store gc
    

Generation Management

  • List System Generations: Shows all past system configurations (generations).

    sudo nix-env --list-generations --profile /nix/var/nix/profiles/system
    
  • Switch Generation (No Reboot): Allows you to roll back to a previous system configuration without restarting.

    1. List generations:

      nix-env --list-generations -p /nix/var/nix/profiles/system
      
    2. Switch to generation:

      sudo nix-env --switch-generation <number> -p /nix/var/nix/profiles/system
      
    3. Activate configuration:

      sudo /nix/var/nix/profiles/system/bin/switch-to-configuration switch
      
    4. Set Booted Generation as Default: If you boot into an older generation, run this to make it the default.

      /run/current-system/bin/switch-to-configuration boot
      

System Rebuilding

  • Rebuild without Cache: Forces a rebuild without using cached tarballs.
    sudo nixos-rebuild switch --flake .#host --option tarball-ttl 0
    
  • Rebuild on a Remote Machine: Uses sudo on a remote machine during activation.
    nixos-rebuild --use-remote-sudo switch --flake .#host
    

Flake Management

  • Update Flake Inputs: Updates flake dependencies and commits to flake.lock.

    nix flake update --commit-lock-file --accept-flake-config
    
  • Inspect Flake Metadata: Shows flake metadata in JSON format.

    nix flake metadata --json | nix run nixpkgs#jq
    

Development & Packaging

  • Prefetch URL: Downloads a file and prints its hash. Essential for packaging.

    nix-prefetch-url "https://discord.com/api/download?platform=linux&format=tar.gz"
    
  • Evaluate a Nix File: Tests a Nix expression from a file.

    nix-eval --file default.nix
    

Nixpkgs Legacy: Using Old OpenSSH with DSS

Sometimes you need to connect to legacy SSH servers that only support ssh-dss (DSA) keys. Modern Nixpkgs disables DSS by default, but you can pin an older package.

1. Create a Nix file for legacy OpenSSH

legacy-ssh.nix:

{ pkgs ? import <nixpkgs> {} }:

let
  # Pin an older nixpkgs commit with DSS support
  legacyPkgs = import (builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/2f6ef9aa6a7eecea9ff7e185ca40855f36597327.tar.gz";
    sha256 = "0jcs9r4q57xgnbrc76davqy10b1xph15qlkvyw1y0vk5xw5vmxfz";
  }) {};
in
  legacyPkgs.openssh

Browse older package versions: Nix Versions

2. Build the package

nix build -f legacy-ssh.nix

3. Use the legacy ssh binary

./result/bin/ssh -F /dev/null \
  -o HostKeyAlgorithms=ssh-dss \
  -o KexAlgorithms=diffie-hellman-group1-sha1 \
  -o PreferredAuthentications=password,keyboard-interactive \
  admin@192.168.0.1 -vvv

Explanation of key options:

  • -F /dev/null β†’ Ignore default SSH config.
  • HostKeyAlgorithms=ssh-dss β†’ Allow DSS host keys.
  • KexAlgorithms=diffie-hellman-group1-sha1 β†’ Use legacy key exchange.
  • PreferredAuthentications=password,keyboard-interactive β†’ Only use password or interactive login.

Arch Linux Installation Guide

This guide provides step-by-step instructions for installing Arch Linux.

Table of Contents

  1. Keyboard Layout Setup
  2. Connecting to Wi-Fi
  3. SSH Connection to Another Device
  4. Date and Time Setup
  5. Disk Management for Installation
  6. System Installation
  7. Configuring the New Installation (arch-chroot)
  8. Edit The Mkinitcpio File For Encrypt
  9. Grub Installation
  10. Enabling Systemd Services
  11. Creating a New User
  12. Finishing the Installation
  13. Post-Installation Configuration

1. Keyboard Layout Setup

Load the keyboard layout using the following commands:

localectl
localectl list-keymaps
localectl list-keymaps | grep us
loadkeys us

Explanation:

  • localectl: Lists the current keyboard layout settings.
  • localectl list-keymaps: Lists all available keyboard layouts.
  • localectl list-keymaps | grep us: Filters the list to show only layouts containing "us" (United States layout).
  • loadkeys us: Sets the keyboard layout to US.

2. Connecting to Wi-Fi

Connect to a Wi-Fi network using the following commands:

iwctl
device list
station wlan0 get-networks
station wlan0 connect wifiname
ip a
ping -c 5 google.com

Explanation:

  • iwctl: Launches the interactive Wi-Fi control utility.
  • device list: Lists available network devices.
  • station wlan0 get-networks: Scans for available Wi-Fi networks.
  • station wlan0 connect wifiname: Connects to the specified Wi-Fi network (replace "wifiname" with the actual network name).
  • ip a: Displays the network interfaces and their IP addresses.
  • ping -c 5 google.com: Pings the Google website to test the internet connection.

3. SSH Connection to Another Device

Set a password and establish an SSH connection to another device:

passwd
ssh root@ipaddress

Explanation:

  • passwd: Sets the password for the current device (root user).
  • ssh root@ipaddress: Connects to the current device using SSH from another device (replace "ipaddress" with the actual IP address of the current device).

4. Date and Time Setup

Set the date and time for the system:

timedatectl
timedatectl list-timezones
timedatectl list-timezones | grep Dhaka
timedatectl set-timezone Asia/Dhaka
timedatectl

Explanation:

  • timedatectl: Displays the current system time and date settings.
  • timedatectl list-timezones: Lists all available time zones.
  • timedatectl list-timezones | grep Dhaka: Filters the list to

show time zones containing "Dhaka" (replace with your desired time zone).

  • timedatectl set-timezone Asia/Dhaka: Sets the system's time zone to "Asia/Dhaka" (replace with your desired time zone).
  • timedatectl: Verifies the updated time and date settings.

5. Disk Management for Installation

Manage the disk partitions for the installation:

lsblk
ls /sys/firmware/efi/efivars
blkid /dev/vda
cfdisk
lsblk
mkfs.btrfs -f /dev/vda1
mkfs.fat -F32 /dev/vda2
blkid /dev/vda
mount /dev/vda1 /mnt
cd /mnt
btrfs subvolume create @
btrfs subvolume create @home
cd
umount /mnt
mount -o noatime,ssd,space_cache=v2,compress=zstd,discard=async,subvol=@ /dev/vda1 /mnt
mkdir /mnt/home
mount -o noatime,ssd,space_cache=v2,compress=zstd,discard=async,subvol=@home /dev/vda1 /mnt/home
mkdir -p /mnt/boot/efi
mount /dev/vda2 /mnt/boot/efi

mkdir /mnt/windows
lsblk

Explanation:

  • lsblk: Lists available block devices and their partitions.
  • ls /sys/firmware/efi/efivars: Verifies if the system is booted in UEFI mode.
  • blkid /dev/sda: Displays information about the /dev/sda drive (replace with the appropriate drive if different).
  • cfdisk : # create two pertion 1. Main file 2. efi partion

disk encryption

  • cryptsetup luksformat /dev/vda1: setup encryption

  • cryptsetup luksOpen /dev/vda1 main: open your encrypted partition

  • lsblk: Lists the updated block devices and their partitions after partitioning.

  • mkfs.btrfs -f /dev/mapper/main: Formats the System partition (/dev/vda1 or (main)) as Btrfs.

  • mkfs.fat -F32 -f /dev/vda2: Formats the EFI System partition (/dev/vda2) as FAT32.

  • blkid /dev/vda: Verifies the UUID of the formatted partition.

  • mount /dev/mapper/main /mnt: Mounts the System partition (main) to the /mnt directory.

  • cd /mnt: Changes the current directory to /mnt.

  • fat subvolume create @: Creates a Btrfs subvolume named "@" for the root directory.

  • fat subvolume create @home: Creates a Btrfs subvolume named "@home" for the home directory.

  • cd: Returns to the previous directory.

  • umount /mnt: Unmounts the /mnt directory.

  • mount -o noatime,ssd,space_cache=v2,compress=zstd,discard=async,subvol=@ /dev/vda1 /mnt: Mounts the System partition (/dev/vda1) with Btrfs subvolume "@", applying specified mount options.

  • mkdir /mnt/home: Creates the /mnt/home directory.

  • mount -o noatime,ssd,space_cache=v2,compress=zstd,discard=async,subvol=@home /dev/vda1 /mnt/home: Mounts the System partition (/dev/vda1) with Btrfs subvolume "@home" to the /mnt/home directory, applying specified mount options.

  • mkdir -p /mnt/boot/efi: Creates the /mnt/boot/efi directory.

  • mount /dev/vda1 /mnt/boot/efi: Mounts the EFI System partition (/dev/vda2) to the /mnt/boot/efi directory.

(Optional) For Windows partition:

  • mkdir /mnt/windows: Creates the /mnt/windows directory.
  • lsblk: Lists available block devices and their partitions to identify the Windows partition.

6. System Installation

Install the base system:

reflector --country Bangladesh --age 6 --sort rate --save /etc/pacman.d/mirrorlist
pacman -Sy
pacstrap -K /mnt base linux linux-firmware intel-ucode vim
genfstab -U /mnt >> /mnt/etc/fstab
cat /mnt/etc/fstab

Explanation:

  • reflector --country Bangladesh --age 6 --sort rate --save /etc/pacman.d/mirrorlist: Updates the mirrorlist file with the fastest mirrors in Bangladesh (replace with your desired country).
  • pacman -Sy: Synchronizes package databases.
  • pacstrap -K /mnt base linux linux-firmware intel-ucode vim: Installs essential packages (replace with any additional packages you may need).
  • genfstab -U /mnt >> /mnt/etc/fstab: Generates an fstab file based on the current disk configuration.
  • cat /mnt/etc/fstab: Displays the contents of the generated fstab file for verification.

7. Configuring the New Installation (arch-chroot)

Enter the newly installed system for configuration:

arch-chroot /mnt
ls
ln -sf /usr/share/zoneinfo/Asia/Dhaka /etc/localtime
hwclock --systohc
vim /etc/locale.gen
locale-gen
echo "LANG=en_US.UTF-8" >> /etc/locale.conf
echo "KEYMAP=us" >> /etc/vconsole.conf
vim /etc/hostname
passwd
pacman -S grub-btrfs efibootmgr networkmanager network-manager-applet dialog wpa_supplicant mtools dosfstools reflector base-devel linux-headers bluez bluez-utils cups hplip alsa-utils pipewire pipewire-alsa pipewire-pulse pipewire-jack bash-completion openssh rsync acpi acpi_call tlp sof-firmware acpid os-prober ntfs-3g

Explanation:

  • arch-chroot /mnt: Changes the root to the newly installed system (/mnt).
  • ls: Lists the contents of the root directory to verify the chroot environment.
  • ln -sf /usr/share/zoneinfo/Asia/Dhaka /etc/localtime: Creates a symbolic link from the system's time zone file to /etc/localtime, setting the system's time zone to "Asia/Dhaka" (replace with your desired time zone).
  • hwclock --systohc: Sets the hardware clock from the system clock.
  • vim /etc/locale.gen: Opens the locale.gen file for editing.
    • Uncomment the line containing "en_US.UTF-8" by removing the leading "#" character.
  • locale-gen: Generates the locales based on the uncommented entries in locale.gen.
  • echo "LANG=en_US.UTF-8" >> /etc/locale.conf: Sets the LANG variable in locale.conf to "en_US.UTF-8".
  • echo "KEYMAP=us" >> /etc/vconsole.conf: Sets the KEYMAP variable in vconsole.conf to "us" (replace with your desired keyboard layout).
  • vim /etc/hostname: Opens the hostname file for editing.
    • Set the hostname to "arch" (replace with your desired hostname).
  • passwd: Sets the root password.
  • pacman -S grub efibootmgr networkmanager network-manager-applet dialog wpa_supplicant mtools dosfstools reflector base-devel linux-headers bluez bluez-utils cups hplip alsa-utils pipewire pipewire-alsa pipewire-pulse pipewire-jack bash-completion openssh rsync acpi acpi_call tlp sof-firmware acpid os-prober ntfs-3g: Installs various packages necessary for the system, including GRUB, network management tools, Bluetooth support, printer support, audio utilities, and other useful packages. Adjust the list based on your requirements.

8. Edit The Mkinitcpio File For Encrypt

  • vim /etc/mkinitcpio.conf and search for HOOKS;
  • add encrypt (before filesystems hook);
  • add atkbd to the MODULES (enables external keyboard at device decryption prompt);
  • add btrfs to the MODULES; and,
  • recreate the mkinitcpio -p linux

9. Grub Installation

Install and configure Grub:

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB
grub-mkconfig -o /boot/grub/grub.cfg

vim /etc/default/grub
grub-mkconfig -o /boot/grub/grub.cfg
  • run blkid and obtain the UUID for the main partitin: blkid /dev/vda1
  • edit the grub config nvim /etc/default/grub
  • GRUB_CMDLINE_LINUX_DEFAULT="loglevel=3 quiet cryptdevice=UUID=d33844ad-af1b-45c7-9a5c-cf21138744b4:main root=/dev/mapper/main
  • make the grub config with grub-mkconfig -o /boot/grub/grub.cfg

Explanation:

  • grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=GRUB: Installs GRUB bootloader on the EFI System partition (/dev/vda2) with the bootloader ID "GRUB".
  • grub-mkconfig -o /boot/grub/grub.cfg: Generates the GRUB configuration file based on the installed operating systems.
  • vim /etc/default/grub: Opens the GRUB configuration file for editing.
    • Uncomment the line with "os-prober" by removing the leading "#" character. This allows GRUB to detect other installed operating systems.
  • grub-mkconfig -o /boot/grub/grub.cfg: Generates the GRUB configuration file again to include the changes made.

10. Enabling Systemd Services

Enable necessary systemd services:

systemctl enable NetworkManager
systemctl enable bluetooth
systemctl enable cups.service
systemctl enable sshd
systemctl enable tlp
systemctl enable reflector.timer
systemctl enable fstrim.timer
systemctl enable acpid

Explanation:

  • systemctl enable NetworkManager: Enables the NetworkManager service to manage network connections.
  • systemctl enable bluetooth: Enables the Bluetooth service.
  • systemctl enable cups.service: Enables the CUPS (Common Unix Printing System) service for printer support.
  • systemctl enable sshd: Enables the SSH server for remote access.
  • systemctl enable tlp: Enables the TLP service for power management.
  • systemctl enable reflector.timer: Enables the Reflector timer to update the mirrorlist regularly.
  • systemctl enable fstrim.timer: Enables the fstrim timer to trim the filesystem regularly.
  • systemctl enable acpid: Enables the ACPI (Advanced Configuration and Power Interface) service.

11. Creating a New User

Create a new user and grant sudo access:

useradd -m akib
passwd akib
echo "akib ALL=(ALL) ALL" >> /etc/sudoers.d/akib
usermod -c 'Akib Ahmed' akib
exit

Explanation:

  • useradd -m akib: Creates a new user account named "akib" with the -m flag to create the user's home directory.
  • passwd akib: Sets the password for the newly created user "akib".
  • echo "akib ALL=(ALL) ALL" >> /etc/sudoers.d/akib: Grants sudo access to the user "akib" by adding a sudoers file for the user.
  • usermod -c 'Akib Ahmed' akib: Sets the user's full name as "Akib Ahmed" (replace with the desired full name).
  • exit: Exits the chroot environment.

12. Finishing the Installation

Unmount partitions and reboot the system:

umount -R /mnt
reboot

Explanation:

  • umount -R /mnt: Unmounts all the partitions mounted under /mnt.
  • reboot: Reboots the system.

Once the system reboots, you can log in with the newly created user and continue the setup process.

13. Post-Installation Configuration

After logging in with the newly created user, perform the following steps:

nmtui
  • Opens the NetworkManager Text User Interface (TUI) for managing network connections.
ip -c a
  • Displays the IP addresses and network interfaces for verification.
grub-mkconfig -o /boot/grub/grub.cfg
  • Generates the GRUB configuration file to include any changes made during the post-installation steps.
sudo pacman -S git
  • Installs the Git package.
git clone https://aur.archlinux.org/yay-bin.git
  • Clones the Yay AUR (Arch User Repository) package from the AUR repository.
ls
cd yay-bin/
makepkg -si
cd
  • Changes directory to the cloned "yay-bin" directory, builds the package, and installs it using makepkg.
yay
  • Verifies the successful installation of Yay by running the command.
yay -S timeshift-bin timeshift-autosnap
  • Installs the Timeshift packages from the AUR using Yay.
sudo timeshift --list-devices
  • Lists the available devices for creating Timeshift snapshots.
sudo timeshift --snapshot-device /dev/vda1
  • Sets the device (/dev/vda1) to be used for creating Timeshift snapshots.
sudo timeshift --create --comments "First Backup" --tags D
  • Creates a Timeshift snapshot with a comment and assigns it the "D" tag for easy identification.
sudo grub-mkconfig -o /boot/grub/grub.cfg
  • Generates the GRUB configuration file again to include any changes made during the post-installation steps.

Ensure you have read and understood each step before proceeding. These additional steps cover various post-installation configurations, including network setup, package installation with Yay, and creating a Timeshift backup.

Happy Arch Linux configuration! 🐧

Gentoo Installation Guide

This comprehensive guide provides a detailed walkthrough for installing Gentoo Linux. Adjustments may be required based on your specific hardware and preferences.

Prerequisites

  • A reliable internet connection.
  • A virtual or physical machine with a target disk (e.g., /dev/vdx).

1. Check Internet Connection

Make sure your internet connection is working:

ping -c 5 www.google.com

2. Disk Partitioning

Partition your disk using fdisk:

fdisk /dev/vdx

Follow these steps in fdisk:

  • Press g for GPT partition.
  • Create partitions for boot, swap, and root using n.
  • Change partition labels using t: set boot to EFI, swap to Linux swap.

Format partitions:

mkfs.vfat -F 32 /dev/vdx1
mkswap /dev/vdx2
swapon /dev/vdx2
mkfs.ext4 /dev/vdx4

Mount the root partition:

mkdir -p /mnt/gentoo
mount /dev/sda3 /mnt/gentoo

3. Installing a Stage Tarball

Navigate to the Gentoo mirrors and download the stage3 tarball:

cd /mnt/gentoo
links https://www.gentoo.org/downloads/mirrors/
tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner
vi /mnt/gentoo/etc/portage/make.conf 

In make.conf, specify your CPU architecture and core:

COMMON_FLAGS="-march=alderlake -O2 -pipe"
MAKEOPTS="-j8"
FEATURES="candy parallel-fetch parallel-install"
ACCEPT_LICENSE="*"

4. Installing the Gentoo Base System

Select a mirror:

mirrorselect -i -o >> /mnt/gentoo/etc/portage/make.conf

Create necessary directories:

mkdir -p /mnt/gentoo/etc/portage/repos.conf
cp /mnt/gentoo/usr/share/portage/config/repos.conf /mnt/gentoo/etc/portage/repos.conf/gentoo.conf
cp --dereference /etc/resolv.conf /mnt/gentoo/etc/

Mount essential filesystems:

mount --types proc /proc /mnt/gentoo/proc
mount --rbind /sys /mnt/gentoo/sys
mount --make-rslave /mnt/gentoo/sys
mount --rbind /dev /mnt/gentoo/dev
mount --make-rslave /mnt/gentoo/dev
mount --bind /run /mnt/gentoo/run
mount --make-slave /mnt/gentoo/run

Chroot into the new environment:

chroot /mnt/gentoo /bin/bash
source /etc/profile
export PS1="(chroot) ${PS1}"

Mount the EFI boot partition:

mkdir /efi
mount /dev/sda1 /efi

5. Configuring Portage Package Manager of Gentoo

emerge-webrsync
emerge --sync
emerge --sync --quiet
eselect profile list
eselect profile set 9
emerge --ask --verbose --update --deep --newuse @world
nano /etc/portage/make.conf

In make.conf, add USE flags:

USE="-gtk -gnome qt5 kde dvd alsa cdr"

Create a package.license directory and edit the kernel license:

mkdir /etc/portage/package.license
nvim /etc/portage/package.license/kernel

Add the following licenses:

app-arch/unrar unRAR
sys-kernel/linux-firmware @BINARY-REDISTRIBUTABLE
sys-firmware/intel-microcode intel-ucode

6. Timezone and Locale Configuration

Set your timezone:

ls /usr/share/zoneinfo
echo "Asia/Dhaka" > /etc/timezone
emerge --config sys-libs/timezone-data

Configure locales:

emerge app-editors/neovim
nvim /etc/locale.gen

Uncomment the necessary locales and set the default:

en_US ISO-8859-1
en_US.UTF-8 UTF-8

Set the locale:

locale-gen
eselect locale list
eselect locale set 6
env-update && source /etc/profile && export PS1="(chroot) ${PS1}"

7. Configuring the Kernel

emerge --ask sys-kernel/linux-firmware
emerge --ask sys-kernel/gentoo-sources
eselect kernel list
eselect kernel set 1
emerge --ask sys-apps/pciutils
cd /usr/src/linux
make menuconfig
make && make modules_install
make install

Alternatively, use Genkernel:

emerge --ask sys-kernel/linux-firmware
emerge --ask sys-kernel/genkernel
genkernel --mountboot --install all
ls /boot/vmlinu* /boot/initramfs*
ls /lib/modules 

Or, Use the binary kernel:

emerge --ask sys-kernel/gentoo-kernel
emerge --ask --autunmust-write sys-kernel/gentoo-kernel-bin
etc-update
emerge -a sys-kernel/gentoo-kernel-bin

8. Configuring Fstab and Networking

Edit fstab to reflect your disk configuration:

neovim /etc/fstab

Add entries for EFI, swap, and root partitions:

/dev/vdx1   /efi        vfat    defaults    0 2
/dev/vdx2   none        swap    sw          0 0
/dev/vdx3   /           ext4    defaults,noatime 0 1

Configure networking:

echo virt > /etc/hostname
emerge --ask --noreplace net-misc/netifrc
nvim /etc/conf.d/net

Add your network configuration:

config_enp1s0="dhcp"

Set networking to start at boot:

cd /etc/init.d
ln -s net.lo net.enp1s0
rc-update add net.enp1s0 default


9. Editing Hosts and System Configuration

Edit the hosts file:

nano /etc/hosts

Add or edit the hosts file with appropriate entries:

127.0.0.1     virt    localhost
::1           virt    localhost

Set system information:

passwd
nano /etc/conf.d/hwclock

Edit hwclock configuration:

clock="local"

10. System Logger and Additional Software

emerge --ask app-admin/sysklogd
rc-update add sysklogd default
rc-update add sshd default
nano -w /etc/inittab

Add SERIAL CONSOLES configuration:

s0:12345:respawn:/sbin/agetty 9600 ttyS0 vt100
s1:12345:respawn:/sbin/agetty 9600 ttyS1 vt100

Install additional software:

emerge --ask sys-fs/e2fsprogs
emerge --ask sys-block/io-scheduler-udev-rules
emerge --ask net-misc/dhcpcd
emerge --ask net-dialup/ppp
emerge --ask net-wireless/iw net-wireless/wpa_supplicant

11. Boot Loader

echo 'GRUB_PLATFORMS="efi-64"' >> /etc/portage/make.conf
emerge --ask --verbose sys-boot/grub
grub-install --target=x86_64-efi --efi-directory=/efi
grub-mkconfig -o /boot/grub/grub.cfg
exit
cd
umount -l /mnt/gentoo/dev{/shm,/pts,}
umount -R /mnt/gentoo
reboot

12. Adding a User for Daily Use

useradd -m -G users,wheel,audio -s /bin/bash akib
passwd akib

Removing Tarballs

rm /stage3-*.tar.*

13. Sound (PipeWire) Setup

emerge -av media-libs/libpulse
emerge --ask media-video/pipewire
emerge --ask media-video/wireplumber
usermod -aG pipewire akib
emerge --ask sys-auth/rtkit
usermod -rG audio akib

mkdir /etc/pipewire
cp /usr/share/pipewire/pipewire.conf /etc/pipewire/pipewire.conf

mkdir ~/.config/pipewire
cp /usr/share/pipewire/pipewire.conf ~/.config/pipewire/pipewire.conf

Add the following configuration to ~/.config/pipewire/pipewire.conf:

context.properties = {
    default.clock.rate = 192000
    default.clock.allowed-rates = [ 192000 48000 44100 ]  # Up to 16 can be specified
}

14. Xorg Setup

Edit /etc/portage/make.conf and add the following:

USE="X"
INPUT_DEVICES="libinput synaptics"
VIDEO_CARDS="nouveau"
VIDEO_CARDS="radeon"

Install Xorg drivers and server:

emerge --ask --verbose x11-base/xorg-drivers
emerge --ask x11-base/xorg-server
env-update
source /etc/profile

15. Setting up Display Manager (SDDM)

emerge --ask x11-misc/sddm
usermod -a -G video sddm
vim /etc/sddm.conf

Add the following lines:

[X11]
DisplayCommand=/etc/sddm/scripts/Xsetup

Create /etc/sddm/scripts/Xsetup:

mkdir -p /etc/sddm/scripts
chmod a+x /etc/sddm/scripts/Xsetup

Edit /etc/conf.d/xdm and add:

DISPLAYMANAGER="sddm"

Enable the display manager at boot:

rc-update add xdm default
emerge --ask gui-libs/display-manager-init
vim /etc/conf.d/display-manager

From there add,

		CHECKVT=7
		DISPLAYMANAGER="sddm"

after that add it to the service,

rc-update add display-manager default
rc-service display-manager start

16. Desktop Installation (KDE Plasma)

eselect profile list
eselect profile set X

Set the number according to the desktop environment you want. For KDE Plasma:

emerge --ask kde-plasma/plasma-meta
emerge konsole
emerge firefox-bin

Create ~/.xinitrc and add:

#!/bin/sh
exec dbus-launch --exit-with-session startplasma-x11

Feel free to customize this guide further based on your specific needs and preferences.

This guide is designed to provide a comprehensive and detailed walkthrough for installing Gentoo Linux. Feel free to customize it further based on your specific needs and preferences.

Linux Command Reference

This is a reference guide for commonly used Linux commands. The following commands are available in most Linux distributions and can be accessed from the command line interface (CLI).

Table of Contents

Commands

A

  • alias - Create an alias for a command.
  • apropos - Search the manual page names and descriptions.
  • awk - Pattern scanning and processing language.

B

  • basename - Strip directory and suffix from a file path.
  • bg - Run a job in the background.
  • break - Exit from a loop.
  • builtin - Run a shell builtin command.

C

  • cal - Display a calendar.
  • cat - Concatenate and display files.
  • cd - Change the current directory.
  • chmod - Change file mode bits/permissions.
  • chown - Change file ownership.
  • chroot - Run a command with a different root directory.
  • cksum - Print CRC checksum and byte counts.
  • clear - Clear the terminal screen.
  • cmp - Compare two files byte by byte.
  • comm - Compare two sorted files line by line.
  • command - Run a command bypassing shell functions.
  • continue - Resume the next iteration of a loop.
  • cp - Copy files and directories.
  • cron - Daemon to execute scheduled commands.
  • crontab - Schedule a command to run at a specific time.
  • csplit - Split files based on context.
  • cut - Remove sections from each line of files.

D

  • date - Print or set the system date and time.
  • dd - Convert and copy a file.
  • df - Display disk space usage.
  • diff - Compare files line by line.
  • diff3 - Show differences among three files.
  • dirs - Display the list of currently remembered directories.
  • disown - Remove jobs from current shell.

E

  • echo - Print arguments to the standard output.
  • egrep - Search files for a pattern using extended regular expressions.
  • elif - Conditional statement in a shell script.
  • else - Conditional statement in a shell script.
  • env - Display or set environment variables.
  • esac - Conditional statement in a shell script.
  • eval - Evaluate several commands/arguments.
  • exec - Replace the current process with a new process.

F

  • false - Do nothing, unsuccessfully.
  • fc - Fix command line.
  • fg - Run a job in the foreground.
  • file - Determine file type.
  • find - Search files and directories.
  • fmt - Reformat paragraph text.
  • for - Loop command.

G

  • gawk - Pattern scanning and processing language.
  • getopts - Parse positional parameters.
  • grep - Search files for a pattern.
  • groups - Print the group names of the current user.

H

  • hash - Remember the full pathnames of commands.
  • head - Output the first part of files.
  • help - Display help information.
  • history - Command history.
  • hostname - Print or set the system's host name.

I

  • id - Print user and group information.
  • if - Conditional statement in a shell script.
  • in - Loop command.
  • info - Help information.
  • install - Copy files and set attributes.
  • jobs - List active jobs.

J

  • jobs - List active jobs.
  • join - Join lines of files.

K

  • kill - Terminate a process.

L

  • less - Display file contents.
  • let - Evaluate arithmetic expressions.
  • ln - Create links.
  • local - Define local variables.
  • locate - Find files by name.
  • logname - Print the current login name.

M

  • make - GNU make utility to maintain groups of programs.
  • man - Display manual page.
  • mkdir - Create directories.
  • mkfifo - Make FIFOs (named pipes).
  • more - Display file contents.
  • mv - Move/rename files or directories.

N

  • nice - Set the priority of a command.
  • nohup - Run a command immune to hangups.
  • notify-send - Send desktop notifications.
  • now - Print the current date and time.

O

  • open - Open a file or directory.
  • op - An application to handle cryptographic operations.

P

  • passwd - Change user password.
  • paste - Merge lines of files.
  • ping - Send ICMP ECHO_REQUEST to network hosts.
  • popd - Change the current directory to the previous directory.
  • printenv - Print environment variables.
  • printf - Format and print data.
  • ps - Report a snapshot of the current processes.
  • pushd - Change the current directory to a specified directory.

Q

  • quota - Display disk usage and limits.

R

  • read - Read a line from standard input.
  • readonly - Mark variables or functions as read-only.
  • reboot - Reboot the system.
  • rename - Rename files.
  • return - Exit a function.
  • rev - Reverse lines of a file.
  • rm - Remove files or directories.
  • rmdir - Remove empty directories.
  • rsync - Remote file copy (Synchronization).
  • run-parts - Run scripts or programs in a directory.

S

  • screen - Terminal multiplexer.
  • sed - Stream editor for filtering and transforming text.
  • select - Generate a menu in a shell script.
  • seq - Print numeric sequences.
  • set - Set shell options.
  • shift - Shift positional parameters.
  • shopt - Shell options.
  • shutdown - Shutdown or restart the system.
  • sleep - Delay for a specified time.
  • sort - Sort lines of text files.
  • source - Execute commands from a file.
  • split - Split a file into pieces.
  • ssh - Secure Shell client.
  • su - Substitute user identity.
  • sudo - Execute a command as another user.
  • sum - Print checksum and block counts.
  • suspend - Suspend the execution of the current shell.
  • symlink - Create a symbolic link to a file.

T

  • tail - Output the last part of files.
  • tar - Manipulate archive files.
  • tee - Read from standard input and write to standard output and files.
  • test - Evaluate a conditional expression.
  • time - Measure program execution time.
  • times - Print the accumulated user and system times.
  • touch - Change file timestamps.
  • tr - Translate or delete characters.
  • trap - Run a command when a signal is set.
  • true - Do nothing, successfully.
  • tty - Print the file name of the terminal connected to standard input.
  • type - Describe a command.

U

  • ulimit - Set or report file size limit.
  • umask - Set the file mode creation mask.
  • unalias - Remove an alias.
  • uname - Print system information.
  • uniq - Uniquify files.
  • unset - Remove variable or function names.
  • until - Loop command.

V

  • vi - Text editor.
  • vmstat - Report virtual memory statistics.

W

  • wait - Wait for a process to complete.
  • wc - Print newline, word, and byte counts.
  • while - Loop command.
  • who - Print who is currently logged in.
  • whoami - Print the current user.

X

  • xargs - Execute utility, passing constructed argument lists.
  • xdg-open - Open a file or URL in the user's preferred application.
  • xxd - Make a hexdump or do the reverse.

Y

  • yes - Output a string repeatedly.

Z

  • zcat - Concatenate and display compressed files.

🐚 Bash Cheat Sheet

This cheat sheet helps you navigate, automate, and debug efficiently in Bash. It covers file operations, permissions, variables, regex, flow control, and more.

Useful for:

  • Linux/Mac users
  • System administrators
  • Security professionals
  • Students (LPIC, OSCP, etc.)

πŸ“‚ File Test Operators

Check file types and permissions in scripts.

FlagDescription
-eFile exists
-fRegular file (not directory/device)
-dDirectory
-sFile is not empty
-rRead permission
-wWrite permission
-xExecute permission
-LSymbolic link
-OYou own the file
f1 -nt f2f1 is newer than f2
f1 -ef f2Hard links to the same file

Example:

if [ -f "/etc/passwd" ]; then
  echo "File exists"
fi

πŸ”’ Integer Comparisons

OperatorDescription
-eqEqual
-neNot equal
-gtGreater than
-ltLess than
-geGreater or equal
-leLess or equal

Example:

a=5; b=10
if [ "$a" -lt "$b" ]; then
  echo "a is less than b"
fi

πŸ”€ String Comparisons

OperatorDescription
= / ==Equal
!=Not equal
-zString is empty
-nString is not empty

Example:

str="hello"
if [ -n "$str" ]; then
  echo "String is not empty"
fi

πŸ”„ Compound Operators

OperatorDescription
-aLogical AND
-oLogical OR
!NOT

Example:

if [ -r file.txt -a -w file.txt ]; then
  echo "Readable and writable"
fi

βš™οΈ Job Control

NotationMeaning
%% / %+Current job
%-Previous job
%NJob number
%?SJob containing string S

Example:

sleep 100 &
jobs
fg %1

πŸ”€ List Constructs

ConstructDescription
&&Run next if previous succeeds
``Run next if previous fails

Example:

mkdir test && cd test

πŸšͺ Exit Codes

CodeMeaning
0Success
1General error
126Command invoked cannot execute
127Command not found
130Script terminated (Ctrl+C)

Example:

echo "test"
echo $?   # prints 0 if successful

πŸ“‘ Signals & Shortcuts

SignalKeyAction
SIGINTCtrl+CInterrupt
SIGTSTPCtrl+ZSuspend
SIGKILLkill -9 <PID>Force kill

πŸ“œ Permissions

SymbolMeaning
rRead
wWrite
xExecute
sSetUID/SetGID
tSticky bit

Example:

chmod 755 script.sh   # rwxr-xr-x

βœ‚οΈ String Manipulation

ExpressionMeaning
${#var}String length
${var:pos}Substring
${var/pat/rep}Replace first occurrence
${var//pat/rep}Replace all

Example:

text="Hello World"
echo ${#text}       # 11
echo ${text:0:5}    # Hello

πŸ“Œ Command Parameters

SymbolDescription
$0Script name
$1...$9Arguments
$@All args (individually)
$*All args (single string)
$#Number of args
$$Script PID
$?Last exit code

Example:

echo "Script name: $0"
echo "First arg: $1"

πŸ” History Expansion

CommandMeaning
!!Last command
!nn-th command
!stringLast command starting with string
^a^bReplace a with b in last command

🎭 Globbing vs Regex

  • Globbing (filenames):

    • * β†’ any string
    • ? β†’ single char
    • [a-z] β†’ range
  • Regex (text matching):

    • . β†’ any char
    • * β†’ zero or more
    • + β†’ one or more
    • ^ β†’ start of line
    • $ β†’ end of line

Example (globbing):

ls *.txt

Example (regex with grep):

grep "^[0-9]" file.txt

πŸ”„ Flow Control

# If / Else
if [ "$USER" == "akib" ]; then
  echo "Welcome Akib"
else
  echo "Access Denied"
fi

# For loop
for i in {1..5}; do
  echo "Number $i"
done

# While loop
count=1
while [ $count -le 3 ]; do
  echo "Count $count"
  ((count++))
done

βœ… Final Notes

  • Use man bash for full docs
  • Prefer [[ ... ]] over [ ... ] for conditionals
  • Practice with small scripts before automation

Git add and staging area

Commit is for permanently saving your changes to the project’s history, marking a new point in the development timeline.

  1. git add <file> # Adds a file to the staging area.
  2. git add . # Adds all files in the current directory to the staging area.
  3. git commit -m "<message>" # Commits the staging area to the repository with the given message.

Git log and history

  1. git log --graph --oneline # Shows a concise, one-line representation of the commit history with a graphical view.
  2. git log --graph --oneline --decorate --all --simplify-by-decoration # Displays the commit history with a graphical view, showing only commits with tags and branches. The --decorate option adds information about branches and tags.
  3. git reflog # Shows a reference log, which includes all the Git references (branches, tags, etc.) and their associated commit history. Useful for recovering lost commits.

Git head to undo changes

  1. git reset --hard <commit> # Resets the current branch and working directory to the specified commit. Discards all changes after that commit.
  2. git reset --hard origin/master # Resets the current branch to the state of the remote master branch. Useful for discarding local changes and syncing with the remote repository.
  3. git reset --hard HEAD~1 # Resets the current branch and working directory to the previous commit (one commit before the current HEAD).
  4. git reset --soft <commit> # Resets the current branch to the specified commit but keeps the changes in the working directory. The changes will appear as uncommitted modifications.

Git branches

  1. git branch --list # Lists all the local branches in the current repository.
  2. git branch <branch> # Creates a new branch with the given name.
  3. git checkout <branch> # Switches to the specified branch.
  4. git checkout -b <branch> # Creates a new branch with the given name and switches to it.
  5. git branch -d <branch> # Deletes the specified branch.
  6. git branch -m <branch> # Renames the current branch to the specified name.

Git merge

  1. git merge <branch> # Merges the specified branch into the current branch (the one that HEAD points to).
  2. git stash # Temporarily stores all modified tracked files.

Git stash

Stash is for temporarily saving your progress when you need to switch contexts without committing unfinished work.

  1. git stash list # Lists all stashed changesets.
  2. git stash show -p <stash> # Shows the changeset recorded in the stash as a patch.
  3. git stash apply <stash> # Applies the changeset recorded in the stash to the working directory.
  4. git stash pop # Removes and applies the changeset last saved with git stash.

Git mv and rm

  1. git rm <file> # Removes a file from the working directory and staging area.
  2. git rm --cached <file> # Removes a file from the staging area only. After that do git commit
  3. git mv <file-original> <file-renamed> # Renames a file.

Git remote

  1. git remote add origin <url> # Adds a remote repository to the current Git project.
  2. git remote -v # Lists all currently configured remotes.
  3. git remote show <remote> # Shows information about the specified remote.
  4. git remote rename <remote> <new-name> # Renames the specified remote.
  5. git remote remove <remote> # Removes the specified remote.
  6. git push -u origin master # Pushes the master branch to the origin remote and sets it as the default upstream branch for master.
  7. git push origin --delete <branch> # Deletes a remote branch.
  8. git push # Pushes the current branch to the remote repository.
  9. git pull # Pulls the latest changes from the remote repository into the current branch.

Working with Submodules

Let's go through a complete example workflow:

  1. Initial Setup:

    # Navigate to the main repository
    cd ~/path/to/nixos-config
    
    # Add the submodule
    git submodule add https://github.com/username/my-other-repo.git my-other-repo
    
    # Initialize and update the submodule
    git submodule init
    git submodule update
    
    # Commit the submodule addition in the main repository
    git add .gitmodules my-other-repo
    git commit -m "Add my-other-repo as a submodule"
    git push origin main
    
  2. Making Changes in the Submodule:

    # Navigate to the submodule directory
    cd my-other-repo
    
    # Make changes and commit them
    git add .
    git commit -m "Make some changes in the submodule"
    git push origin main
    
    # Navigate back to the main repository
    cd ..
    
    # Update the submodule reference in the main repository
    git add my-other-repo
    git commit -m "Update submodule my-other-repo to latest commit"
    git push origin main
    
  3. Cloning and Updating:

    # Clone the main repository
    git clone https://github.com/username/nixos-config.git
    
    # Navigate into the main repository
    cd nixos-config
    
    # Initialize and update submodules
    git submodule update --init --recursive
    

By following these steps, you can effectively manage submodules in your Git repository, ensuring that both the main repository and the submodules are kept up to date.

Git WorkTree

Using git worktree can greatly enhance your workflow efficiency by allowing you to manage multiple branches in parallel with ease.

# Clone the current repository as a bare repository
git clone --bare . /path/to/my-bare-repo.git

# Add a worktree for the main branch in the default location
git worktree add main

# Add a worktree for the dev branch
git worktree add dev

# Remove the worktree for the dev branch when it's no longer needed
git worktree remove dev

we need to setup into two part

  • client side configuration
  • server side configuration

Server Side Configuration: -

  • To install nfs package sudo apt install nfs-utils libnfsidmap
  • Enable and start nfs service sudo systemctl enable rpcbind, nfs-server sudo systemctl start rpcbind, nfs-server, rpc-statd, nfs-idmap
  • Create a directory for nfs and give all the permission mkdir -p $HOME/Desktop/NFS-Share sudo chmod 777 ~/Desktop/NFS-Share
  • Modify the /etc/exports file and add new shared filesystem /location <IP_allow>(rw,sync,no_root_squash) exportfs -rv

Client Side Configuration:-

  • To install nfs package sudo apt install nfs-utils rpcbind
  • Enable and start the rpcbind service sudo systemctl start rpcbind
  • To stop the firewall sudo systemctl stop firewall / iptable
  • show mount from nfs server showmount -e <IP of server side>
  • Create a mount point (directory) mkdir -p /mnt/share
  • Mount the NFS file system mount <IP_server>:/location /mnt/share

Docker and NGINX Setup Guide

Pull and Run an Ubuntu Docker Container

# Pull the latest Ubuntu image from Docker Hub
docker pull ubuntu

# Run a container from the Ubuntu image, mapping port 80 of the container to port 9090 of the host
docker run -it -p 9090:80 ubuntu

Inside the Ubuntu Container

# Update package lists and upgrade installed packages
apt update && apt upgrade

# Install NGINX and Neovim
apt install nginx neovim

# Verify NGINX installation
nginx -v

# Start NGINX (default port is 80)
nginx

NGINX Configuration Workaround

# Navigate to the NGINX configuration directory
cd /etc/nginx

# Backup the existing nginx.conf file
mv nginx.conf nginx.backup

# Create a new nginx.conf file using Neovim
nvim nginx.conf

# Reload NGINX with the new configuration
nginx -s reload

Basic NGINX Configuration (nginx.conf)

events {
    # Events block (required but can be empty)
}

http {
    # HTTP block to define server and location settings

    server {
        # Server block to handle incoming connections
        listen 80;  # Listen on port 80
        server_name _;  # Handle requests for any server name

        location / {
            # Location block to match the root URL
            return 200 "Hello, World from NGINX";
        }
    }
}

Serving Static Files

# Create a directory for your website
mkdir MyWebSite

# Create an HTML file for the website
touch MyWebSite/index.html

# Create a CSS file for the website
touch MyWebSite/style.css

Sample HTML File (index.html)

<html>
    <head>
        <title>Ahmed X Nginx</title>
        <link rel="stylesheet" href="style.css"/>
    </head>
    <body>
        <h1>Hello From NGINX</h1>
        <p>This is a simple NGINX WebPage</p>
    </body>
</html>

Sample CSS File (style.css)

body {
    background-color: black;
    color: white;
}

Updated NGINX Configuration for Serving Static Files (nginx.conf)

events {
    # Events block (required but can be empty)
}

http {
    # HTTP block to define server and location settings

    # Define MIME types directly (or include from an external file)
    # include /etc/nginx/mime.types;
    types {
        text/css css;
        text/html html;
    }

    server {
        # Server block to handle incoming connections
        listen 80;  # Listen on port 80
        server_name _;  # Handle requests for any server name

        # Define the root directory for static files
        root /etc/nginx/MyWebSite;
    }
}

This guide walks you through setting up a Docker container with Ubuntu, installing and configuring NGINX, and serving static files with a basic website. The comments should help you understand each step and the purpose of each command and configuration block.

Full Node.js Deployment Using Docker

Install Necessary Packages

# Install essential packages including Git, Neovim, NGINX, tmux, Node.js, UFW, and Certbot
apt install git nvim nginx tmux nodejs ufw python3-certbot-nginx

Download Your Project

# Clone the project repository from GitHub
git clone https://github.com/akibahmed229/Java-Employee_Management-System-Website.git

# Change directory to the project folder
cd Java-Employee_Management-System-Website

# Install project dependencies using npm
npm install

Setup and Start the Node.js Application

# Install pm2 globally to manage Node.js processes
sudo npm i pm2 -g

# Start the application using pm2
pm2 start index

# Enable the UFW firewall
ufw enable 

# Allow HTTP traffic on port 80 through the firewall
sudo ufw allow http 80

Configure NGINX as a Reverse Proxy

  1. Edit the NGINX configuration file:

    # Open the NGINX configuration file using Neovim
    nvim /etc/nginx/nginx.conf
    
  2. Ensure the configuration file looks like this:

    events {
        # Events block (required but can be empty)
    }
    
    http {
        # HTTP block to define server and location settings
    
        server {
            # Server block to handle incoming connections
    
            listen 80 default_server;  # Listen on port 80 (IPv4)
            listen [::]:80 default_server;  # Listen on port 80 (IPv6)
            root /var/www/html;  # Define the root directory for static files
            index index.html index.htm index.nginx-debian.html;  # Default index files
    
            server_name localhost;  # Server name (adjust if using a domain)
    
            location / {
                # Location block to match the root URL
    
                proxy_pass http://localhost:5173;  # Proxy requests to the Node.js app
                proxy_http_version 1.1;  # Use HTTP/1.1 for proxying
                proxy_set_header Upgrade $http_upgrade;  # Handle WebSocket upgrades
                proxy_set_header Connection 'upgrade';  # Handle WebSocket upgrades
                proxy_set_header Host $host;  # Preserve the original Host header
                proxy_cache_bypass $http_upgrade;  # Bypass cache for WebSocket upgrades
            }
        }
    }
    

Setup SSL with Certbot

# Obtain and install an SSL certificate for your domain using Certbot
certbot --nginx -d yourdomain.com

# Test the certificate renewal process (certificates are only valid for 90 days)
certbot renew --dry-run

Summary

  1. Install necessary packages: Git, Neovim, NGINX, tmux, Node.js, UFW, Certbot.
  2. Clone the project: Use Git to download your Node.js project.
  3. Install dependencies: Use npm to install project dependencies.
  4. Setup pm2: Manage your Node.js application with pm2.
  5. Configure firewall: Enable UFW and allow HTTP traffic.
  6. Configure NGINX: Set up NGINX as a reverse proxy to forward requests to your Node.js application.
  7. Setup SSL: Use Certbot to secure your application with SSL.

By following these steps, you'll have a fully deployed Node.js application using Docker, NGINX, and SSL for secure communication.

Setting Up SSH Server Between PC and Server

This guide explains how to set up and configure an SSH server to enable secure communication between a client PC and a server.


Prerequisites

  1. A Linux-based PC (client) and server.
  2. SSH package installed on both machines.
  3. Network connectivity between the PC and the server.

Step-by-Step Instructions

Step 1: Install OpenSSH

On both the client and server, install the OpenSSH package:

On the Server:

sudo apt update
sudo apt install openssh-server

On the Client:

sudo apt update
sudo apt install openssh-client

Step 2: Start and Enable SSH Service

Ensure the SSH service is running on the server:

sudo systemctl start ssh
sudo systemctl enable ssh

Check the service status:

sudo systemctl status ssh

Step 3: Configure SSH on the Server

  1. Open the SSH configuration file:

    sudo nano /etc/ssh/sshd_config
    
  2. Modify or verify the following settings:

    • PermitRootLogin: Set to no for security.
    • PasswordAuthentication: Set to yes to allow password-based logins initially (you can disable it after setting up key-based authentication).
  3. Save changes and restart the SSH service:

    sudo systemctl restart ssh
    

Step 4: Determine the Server's IP Address

Find the server's IP address to connect from the client:

ip a

Look for the IP address under the active network interface (e.g., 192.168.x.x).


Step 5: Test SSH Connection from the Client

On the client, open a terminal and connect to the server using:

ssh username@server_ip

Replace username with the server's username and server_ip with the actual IP address.

Example:

ssh user@192.168.1.10

**Step 6: Set Up Key-Based Authentication

  1. On the client, generate an SSH key pair:

    ssh-keygen -t rsa -b 4096
    
  2. Copy the public key to the server: on Linux

    ssh-copy-id username@server_ip
    

    on Windows go to the .ssh folder

scp $env:USERPROFILE/.ssh/id_rsa.pub username@ip:~/.ssh/authorized_keys
  1. Verify key-based login:

    ssh username@server_ip
    
  2. Disable password-based logins for added security:

    • Edit the server's SSH configuration file:

      sudo nano /etc/ssh/sshd_config
      
    • Set PasswordAuthentication to no.

    • Restart the SSH service:

      sudo systemctl restart ssh
      

Step 7: Troubleshooting Common Issues

  • Firewall: Ensure SSH traffic is allowed through the firewall on the server:

    sudo ufw allow ssh
    sudo ufw enable
    
  • Connection Refused: Check if the SSH service is running and the correct IP address is used.

Postfix Config lines

Add the following lines to /etc/postfix/main.cf

relayhost = [smtp.gmail.com]:587 myhostname= your_hostname

Location of sasl_passwd we saved smtp_sasl_password_maps = hash:/etc/postfix/sasl/sasl_passwd

Enables SASL authentication for postfix smtp_sasl_auth_enable = yes smtp_tls_security_level = encrypt

Disallow methods that allow anonymous authentication smtp_sasl_security_options = noanonymous


Create a file under /etc/postfix/sasl/

Filename: sasl_passwd

Add the below line [smtp.gmail.com]:587 email@gmail.com:password

change directory to cd /etc/postfix/sasl change the ownership sudo chown root:root * change the permission sudo chmod 600 *

Convert the sasl_passwd file into db file postmap /etc/postfix/sasl/sasl_passwd

Start the postfix service


To send an email using Linux terminal

echo "Test Mail" | mail -s "Postfix TEST" paul@gmail.com

Linux Command for System Administrator

Basic command for system monitoring

  1. sudo du -a / | sort -n -r | head -n 20 # list disk usage
  2. journalctl | grep "error" # log messages, kernel messages, and other system-related information
  3. dmesg --ctime | grep error # Show kernel ring buffer
  4. sudo journalctl -p 3 -xb # Check the lock file
  5. sudo systemctl --failed # Service that failed to load
  6. du -sh .config # File size of a specific directory
  7. find . -type f -exec grep -l "/dev/nvme0n1" {} + # find file and exce command with grep, {} is the output for each & +,\; is the terminator

Reset password (for forgotten password)

Reser Root

  1. init=/bin/bash # from grub commnad mode, find the kernel line containing linux then add at the end of linux command
  2. ctrl+x or F10 # to save the changes and boot
  3. mount -o remount,rw / # mount the root system for (r,w)
  4. passwd # change the password
  5. reboot -f # force reboot, after that you can boot with new passwd you set

Reser User

  1. rw init=/bin/bash # from grub commnad mode, find the kernel line containing linux then add at the end of linux command
  2. ctrl+x or F10 # to save the changes and boot
  3. passwd username # change the password
  4. reboot -f # force reboot, after that you can boot with new passwd you set

Some useful Command

  1. grep -Irl "akib" . # this will find file contain akib in the current dir
  2. grep -A 3 -B 3 "nvme" flake.nix # this will find nvme in flake.nix file with before and after with 3,3 line
  3. sed -i "s/akib/withNewText/g" file.txt # sed will changes the all occurance with new text in a file
  4. cat /etc/passwd | column -t -s ":" -N USERNAME,PW,UID,GUID,COMMENT,HOME,INTERPRETER -J -n passwdFile # will seperate passwd file based on ":" delemeter and show as column format then the "-J" flag will convert it into json file
  5. cat /etc/passwd | awk -F: 'BEGIN {printf "user\tPW\tUID\tGUID\tCOMMENT\tHOME\tINTERPRETER\n"} {printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $1, $2, $3, $4, $5, $6, $7}'
  6. cat /etc/passwd | column -t -s ":" -N USERNAME,PW,UID,GUID,COMMENT,HOME,INTERPRETER -H PW -O UID,USERNAME,GUID,COMMENT,HOME,INTERPRETER # "-H" remove specific column "-O" reorder column

πŸ› οΈ Common Ports & Protocols Cheat Sheet

A quick reference for well-known TCP/UDP ports and their usage. Useful for students, professionals, and anyone studying for certifications like CCNA, CompTIA, or Security+.


πŸ“Œ Well-Known / System Ports (0 – 1023)

PortServiceProtocolDescription
7EchoTCP, UDPEcho service
19CHARGENTCP, UDPCharacter Generator Protocol (rarely used, vulnerable)
20FTP-dataTCP, SCTPFile Transfer Protocol (data)
21FTPTCP, UDP, SCTPFile Transfer Protocol (control)
22SSH/SCP/SFTPTCP, UDP, SCTPSecure Shell, secure logins, file transfers, port forwarding
23TelnetTCPUnencrypted text communication
25SMTPTCPSimple Mail Transfer Protocol (email routing)
53DNSTCP, UDPDomain Name System
67DHCP/BOOTPUDPDHCP Server
68DHCP/BOOTPUDPDHCP Client
69TFTPUDPTrivial File Transfer Protocol
80HTTPTCP, UDP, SCTPWeb traffic (HTTP/1.x, HTTP/2 over TCP; HTTP/3 uses QUIC/UDP)
88KerberosTCP, UDPNetwork authentication system
110POP3TCPPost Office Protocol (email retrieval)
123NTPUDPNetwork Time Protocol
135Microsoft RPC EPMAPTCP, UDPRemote Procedure Call Endpoint Mapper
137-139NetBIOSTCP, UDPNetBIOS services (name service, datagram, session)
143IMAPTCP, UDPInternet Message Access Protocol
161-162SNMPUDPSimple Network Management Protocol (unencrypted)
179BGPTCPBorder Gateway Protocol
389LDAPTCP, UDPLightweight Directory Access Protocol
443HTTPSTCP, UDP, SCTPSecure web traffic (SSL/TLS)
445Microsoft DS SMBTCP, UDPFile sharing, Active Directory
465SMTPSTCPSMTP over SSL/TLS
514SyslogUDPSystem log protocol
520RIPUDPRouting Information Protocol
546-547DHCPv6UDPDHCP for IPv6 (client/server)
636LDAPSTCP, UDPLDAP over SSL
993IMAPSTCPIMAP over SSL/TLS
995POP3STCP, UDPPOP3 over SSL/TLS

πŸ“Œ Registered Ports (1024 – 49151)

PortServiceProtocolDescription
1025Microsoft RPCTCPRPC service
1080SOCKS proxyTCP, UDPProxy protocol
1194OpenVPNTCP, UDPVPN tunneling
1433MS-SQL ServerTCPMicrosoft SQL Server
1521Oracle DBTCPOracle Database listener
1701L2TPTCPLayer 2 Tunneling Protocol
1720H.323TCPVoIP signaling
1723PPTPTCP, UDPVPN protocol (deprecated)
1812-1813RADIUSUDPAuthentication, accounting
2049NFSUDPNetwork File System
2082-2083cPanelTCP, UDPWeb hosting control panel
2222DirectAdminTCPHosting control panel
2483-2484Oracle DBTCP, UDPInsecure & SSL listener
3074Xbox LiveTCP, UDPOnline gaming
3128HTTP ProxyTCPCommon proxy port
3260iSCSI TargetTCP, UDPStorage protocol
3306MySQLTCPDatabase system
3389RDPTCPWindows Remote Desktop
3690SVNTCP, UDPApache Subversion
3724World of WarcraftTCP, UDPGaming
4333mSQLTCPMini SQL
4444Blaster WormTCP, UDPMalware
5000UPnPTCPUniversal Plug & Play
5060-5061SIPTCP, UDPSession Initiation Protocol (VoIP)
5222-5223XMPPTCP, UDPMessaging protocol
5432PostgreSQLTCPDatabase system
5900-5999VNCTCP, UDPRemote desktop (VNC)
6379RedisTCPIn-memory database
6665-6669IRCTCPInternet Relay Chat
6881-6999BitTorrentTCP, UDPFile sharing
8080HTTP Proxy/AltTCPAlternate web port
8443HTTPS AltTCPAlternate secure web port
9042CassandraTCPNoSQL database
9100Printer (PDL)TCPPrint Data Stream

πŸ“Œ Dynamic / Private Ports (49152 – 65535)

These are used for ephemeral connections and custom apps. Safe to use for internal development/testing.


🎯 Most Common Ports for Exams

If you’re preparing for CCNA / CompTIA exams, focus on these:

PortService
7Echo
20, 21FTP
22SSH/SCP
23Telnet
25SMTP
53DNS
67, 68DHCP
69TFTP
80HTTP
88Kerberos
110POP3
123NTP
137-139NetBIOS
143IMAP
161, 162SNMP
389LDAP
443HTTPS
445SMB
636LDAPS
3389RDP
5060-5061SIP (VoIP)

βœ… Conclusion

Familiarity with ports & protocols is essential for:

  • Building secure applications
  • Troubleshooting network issues
  • Passing certification exams

Keep this cheat sheet handy as a quick reference!

IPv4 Subnetting Cheat Sheet

Subnetting is one of the most fundamental yet challenging concepts in networking. This cheat sheet provides quick references to help you master IPv4 subnetting for certifications, administration, and network design.


IPv4 Subnets

Subnetting allows a host to determine if the destination machine is local or remote. The subnet mask determines how many IPv4 addresses are assignable within a network.

CIDRSubnet Mask# of AddressesWildcard
/32255.255.255.25510.0.0.0
/31255.255.255.25420.0.0.1
/30255.255.255.25240.0.0.3
/29255.255.255.24880.0.0.7
/28255.255.255.240160.0.0.15
/27255.255.255.224320.0.0.31
/26255.255.255.192640.0.0.63
/25255.255.255.1281280.0.0.127
/24255.255.255.02560.0.0.255
/23255.255.254.05120.0.1.255
/22255.255.252.010240.0.3.255
/21255.255.248.02,0480.0.7.255
/20255.255.240.04,0960.0.15.255
/19255.255.224.08,1920.0.31.255
/18255.255.192.016,3840.0.63.255
/17255.255.128.032,7680.0.127.255
/16255.255.0.065,5360.0.255.255
/15255.254.0.0131,0720.1.255.255
/14255.252.0.0262,1440.3.255.255
/13255.248.0.0524,2880.7.255.255
/12255.240.0.01,048,5760.15.255.255
/11255.224.0.02,097,1520.31.255.255
/10255.192.0.04,194,3040.63.255.255
/9255.128.0.08,388,6080.127.255.255
/8255.0.0.016,777,2160.255.255.255
/7254.0.0.033,554,4321.255.255.255
/6252.0.0.067,108,8643.255.255.255
/5248.0.0.0134,217,7287.255.255.255
/4240.0.0.0268,435,45615.255.255.255
/3224.0.0.0536,870,91231.255.255.255
/2192.0.0.01,073,741,82463.255.255.255
/1128.0.0.02,147,483,648127.255.255.255
/00.0.0.04,294,967,296255.255.255.255

Decimal to Binary Conversion

IPv4 addresses are actually 32-bit binary numbers. Subnet masks in binary show which part is the network and which part is the host.

Subnet MaskBinaryWildcardBinary Wildcard
2551111 111100000 0000
2541111 111010000 0001
2521111 110030000 0011
2481111 100070000 0111
2401111 0000150000 1111
2241110 0000310001 1111
1921100 0000630011 1111
1281000 00001270111 1111
00000 00002551111 1111

Why Learn Binary?

  • 1 = Network portion
  • 0 = Host portion
  • Subnet masks must have all ones followed by all zeros.

Example: A /24 (255.255.255.0) subnet reserves 24 bits for network and 8 bits for hosts β†’ 254 usable IPs.

/28 Example: If ISP gives 199.44.6.80/28, you calculate host addresses by binary increments β†’ usable range = .81 - .94.


IPv4 Address Classes

ClassRange
A0.0.0.0 – 127.255.255.255
B128.0.0.0 – 191.255.255.255
C192.0.0.0 – 223.255.255.255
D224.0.0.0 – 239.255.255.255
E240.0.0.0 – 255.255.255.255

Reserved (Private) Ranges

Range TypeIP Range
Class A10.0.0.0 – 10.255.255.255
Class B172.16.0.0 – 172.31.255.255
Class C192.168.0.0 – 192.168.255.255
Localhost127.0.0.0 – 127.255.255.255
Zeroconf (APIPA)169.254.0.0 – 169.254.255.255

Key Terminology

  • Wildcard Mask: Indicates available address bits for matching.
  • CIDR: Classless Inter-Domain Routing, uses /XX notation.
  • Network Portion: Fixed part of IP determined by subnet mask.
  • Host Portion: Variable part of IP usable for devices.

Conclusion

IPv4 subnetting can seem complex, but with practice and binary understanding, it becomes second nature. Keep this sheet handy for quick reference during exams, troubleshooting, or design work.

curl Cheat Sheet

Quick: Practical, consultant-style reference for using curl β€” from basic GETs to file uploads, API interactions, cookies, scripting tips and advanced flags. Friendly tone, focused on getting you productive fast.


Table of contents

  1. What is curl?
  2. Quick examples β€” Web browsing & headers
  3. Downloading files
  4. GET requests
  5. POST requests & forms
  6. API interaction & headers
  7. File uploads with --form / -F
  8. Cookies and sessions
  9. Scripting with curl
  10. Advanced & debugging flags
  11. Partial downloads & ranges
  12. Helpful one-line examples
  13. Etiquette & safety note

What is curl?

curl (client URL) is a command-line tool for transferring data with URL syntax. It supports many protocols (HTTP/S, FTP, SCP, SMTP, IMAP, POP3, etc.) and is ideal for quick checks, automation, scripting, API calls, and sometimes creative (or mischievous) automation.

Use it when you need protocol-level control from the terminal.


Quick examples β€” Web browsing & headers

CommandDescription
curl http://example.comPrint HTML body of http://example.com to stdout
curl --list-only "http://example.com/dir/" (-l)List directory contents (if server allows)
curl --location URL (-L)Follow 3xx redirects
curl --head URL (-I)Fetch HTTP response headers only
curl --head --show-error URLHeaders and errors (helpful for down/unresponsive hosts)

Downloading files

CommandNotes
curl --output hello.html http://example.com (-o)Save output to hello.html
curl --remote-name URL (-O)Save file using remote filename
curl --remote-name URL --output newnameDownload then rename locally
curl --remote-name --continue-at - URLResume partial download (if server supports ranges)
curl "https://site/{a,b,c}.html" --output "file_#1.html"Download multiple variants using brace expansion and # placeholders

Batch download pattern (extract links then download):

curl -L http://example.com/list/ | grep '\.mp4' | cut -d '"' -f 8 | while read i; do curl http://example.com/${i} -O; done

(Adjust grep/cut to the page structure.)


GET requests

CommandDescription
curl --request GET "http://example.com" (-X GET)Explicit GET request (usually optional)
curl -s -w '%{remote_ip} %{time_total} %{http_code}\n' -o /dev/null URLSilent mode with custom output: IP, total time, HTTP code

Example: fetch a JSON API (may require headers or tokens):

curl -X GET 'https://api.example.com/items?filter=all' -H 'Accept: application/json'

POST requests & forms

CommandDescription
curl --request POST URL -d 'key=value' (-X POST -d)Send URL-encoded data in the request body
curl -H 'Content-Type: application/json' --data-raw '{"k":"v"}' URLSend raw JSON payload (set content-type)

Examples with MongoDB Data API (illustrative):

# Insert document
curl --request POST 'https://data.mongodb-api/.../insertOne' \
  --header 'Content-Type: application/json' \
  --header 'api-key: YOUR_KEY' \
  --data-raw '{"dataSource":"Cluster0","database":"db","collection":"c","document":{ "name":"Alice" }}'

# Find one
curl --request POST 'https://data.mongodb-api/.../findOne' \
  --header 'Content-Type: application/json' \
  --header 'api-key: YOUR_KEY' \
  --data-raw '{"filter":{"name":"Alice"}}'

API interaction & headers

CommandDescription
-H / --headerAdd custom HTTP header (Auth tokens, Content-Type, Accept, etc.)
curl --header "Auth-Token:$TOKEN" URLPass bearer or custom tokens in headers
curl --user username:password URLBasic auth (-u username:password)

Examples:

curl -H 'Authorization: Bearer $TOKEN' -H 'Accept: application/json' https://api.example.com/me
curl -u 'user:password' 'https://example.com/protected'

File uploads with --form / -F

Use -F to emulate HTML form file uploads (multipart/form-data).

CommandDescription
curl --form "file=@/path/to/file" URLUpload file (use @ for relative or @/abs/path)
curl --form "field=value" --form "file=@/path" URLMix fields and files in one request

Notes:

  • If the file is in the current directory, you can use @filename.
  • If you supply an absolute path, omit the @ and pass field=/full/path.

Examples:

curl -F "email=test@me.com" -F "submit=Submit" 'https://docs.google.com/forms/d/e/FORM_ID/formResponse' > output.html
curl -F "entry.123456789=@/Users/me/pic.jpg" 'https://example.com/upload' > response.html

Cookies and sessions

CommandDescription
curl --cookie "name=val;name2=val2" URL (-b)Send cookie(s) inline
curl --cookie cookies.txt URLLoad cookies from file (cookies.txt with k=v;... format)
curl --cookie-jar mycookies.txt URL (-c)Save cookies received into mycookies.txt
curl --dump-header headers.txt URL (-D)Dump response headers (includes Set-Cookie)

Cookie file format (simple):

key1=value1;key2=value2

Scripting with curl

curl is a natural fit for bash automation. Example script patterns:

  • Reusable function wrapper for API calls (add auth header once)
  • Download + checksum verification loop
  • Rate-limited loops for polite scraping (sleep between requests)

Example: simple reusable function

api_get(){
  local endpoint="$1"
  curl -s -H "Authorization: Bearer $API_KEY" "https://api.example.com/${endpoint}"
}

api_get "items"

Advanced & debugging flags

FlagPurpose
-hShow help
--versionShow curl version and features
-vVerbose (request/response)
--trace filenameDetailed trace of operations and data
-sSilent mode (no progress meter)
-SShow error when used with -s
-LFollow redirects
--connect-timeoutSeconds to wait for TCP connect
-m / --max-timeMax operation time in seconds
-w / --write-outPrint variables after completion (%{http_code}, %{time_total}, %{remote_ip}, etc.)

Examples:

curl -v https://example.com
curl --trace trace.txt https://twitter.com/
curl -s -w '%{remote_ip} %{time_total} %{http_code}\n' -o /dev/null http://ankush.io
curl -L 'https://short.url' --connect-timeout 0.1

Partial downloads & ranges

Use -r to request byte ranges from HTTP/FTP responses (helpful for resuming or grabbing file snippets).

CommandNotes
curl -r 0-99 http://example.comFirst 100 bytes
curl -r -500 http://example.comLast 500 bytes
curl -r 0-99 ftp://ftp.example.comRanges on FTP (explicit start/end required)

Helpful one-line examples

# Show headers only
curl -I https://example.com

# Save response to file quietly
curl -sL https://example.com -o page.html

# POST JSON and pretty-print reply (using jq)
curl -s -H "Content-Type: application/json" -d '{"name":"A"}' https://api.example.com/insert | jq

# Upload file with field name "file"
curl -F "file=@./image.jpg" https://api.example.com/upload

# Send cookies from file and save response headers
curl -b cookies.txt -D headers.txt https://example.com

# Send URL-encoded form field
curl -d "field1=value1&field2=value2" -X POST https://form-endpoint

Request example (SMS via textbelt β€” use responsibly)

curl -X POST https://textbelt.com/text \
  --data-urlencode phone='+[E.164 number]' \
  --data-urlencode message='Please delete this message.' \
  -d key=textbelt

Response example: {"success":true,...} (service-dependent)


Etiquette & safety note

  • Only target servers or forms you own or have explicit permission to test. Abuse (flooding, unauthorized automation, fraud) is illegal and unethical.
  • Prefer --connect-timeout and rate-limiting in scripts to avoid hammering servers.
  • Keep secrets out of command history β€” use environment variables or --netrc where appropriate.

Nmap Cheat Sheet

Quick: A concise, practical reference for common Nmap workflows β€” target selection, scan types, discovery, NSE usage, output handling, evasion tricks, and useful one-liners. Designed like a consultant's quick-reference: organized by category so you can scan and apply fast.


Table of contents

  1. Overview & Usage Tips
  2. Target Specification
  3. Scan Techniques
  4. Host Discovery
  5. Port Specification
  6. Service & Version Detection
  7. OS Detection
  8. Timing & Performance
  9. Timing Tunables
  10. NSE (Nmap Scripting Engine)
  11. Useful NSE Examples
  12. Firewall / IDS Evasion & Spoofing
  13. Output Formats & Options
  14. Helpful Output Examples & Pipelines
  15. Miscellaneous Flags & Other Commands
  16. Practical Tips & Etiquette

Overview & Usage Tips

  • Run Nmap as root (or with sudo) for the most feature-complete scans (e.g., SYN -sS, raw packets, OS detection).
  • Start with discovery (-sn) and light scans (-T3 -F -sV) to find live hosts before aggressive options.
  • Log results (-oA) so you can re-analyze and resume scans later.
  • Respect scope & permissions β€” scanning networks you don't own can be illegal.

Target Specification

Define which IPs/ranges/subnets Nmap should scan.

Switch / SyntaxExampleDescription
Single IPnmap 192.168.1.1Scan a single host
Multiple IPsnmap 192.168.1.1 192.168.2.1Scan specific hosts
Rangenmap 192.168.1.1-254Scan an IP range
Domainnmap scanme.nmap.orgScan a hostname
CIDRnmap 192.168.1.0/24CIDR subnet scan
-iLnmap -iL targets.txtRead targets from file
-iRnmap -iR 100Scan 100 random hosts
--excludenmap --exclude 192.168.1.1Exclude host(s) from scan

Nmap Scan Techniques

Pick based on stealth, permissions, and speed.

SwitchExampleDescription
-sSnmap 192.168.1.1 -sSTCP SYN scan (stealthy; default with privileges)
-sTnmap 192.168.1.1 -sTTCP connect() scan (no raw socket required)
-sUnmap 192.168.1.1 -sUUDP scan
-sAnmap 192.168.1.1 -sAACK scan (firewall mapping)
-sWnmap 192.168.1.1 -sWWindow scan
-sMnmap 192.168.1.1 -sMMaimon scan
-Anmap 192.168.1.1 -AAggressive β€” OS, version, scripts, traceroute

Host Discovery

Find out which hosts are up before scanning ports or when skipping port scans.

SwitchExampleDescription
-sLnmap 192.168.1.1-3 -sLList scan β€” do not send probes (target listing only)
-snnmap 192.168.1.1/24 -snPing / host discovery only (no port scan)
-Pnnmap 192.168.1.1-5 -PnSkip host discovery (treat all hosts as up)
-PSnmap 192.168.1.1-5 -PS22-25,80TCP SYN discovery on specified ports (80 default)
-PAnmap 192.168.1.1-5 -PA22-25,80TCP ACK discovery on specified ports (80 default)
-PUnmap 192.168.1.1-5 -PU53UDP discovery on specified ports (40125 default)
-PRnmap 192.168.1.0/24 -PRARP discovery (local nets only)
-nnmap 192.168.1.1 -nNever perform DNS resolution

Port Specification

Target specific ports, ranges, or mixed TCP/UDP sets.

SwitchExampleDescription
-pnmap 192.168.1.1 -p 21Scan single port
-pnmap 192.168.1.1 -p 21-100Scan port range
-pnmap 192.168.1.1 -p U:53,T:21-25,80Mix UDP and TCP ports
-p-nmap 192.168.1.1 -p-Scan all TCP ports (1–65535)
Service namesnmap 192.168.1.1 -p http,httpsUse service names instead of numbers
-Fnmap 192.168.1.1 -FFast scan β€” top 100 ports
--top-portsnmap 192.168.1.1 --top-ports 2000Scan top N ports by frequency
-p0- / -p-65535nmap 192.168.1.1 -p0-Open-ended ranges; -p0- will scan from 0 to 65535

Service & Version Detection

Try to identify the service and its version running on discovered ports.

SwitchExampleDescription
-sVnmap 192.168.1.1 -sVService/version detection
-sV --version-intensitynmap 192.168.1.1 -sV --version-intensity 8Intensity 0–9. Higher = more probing
--version-lightnmap 192.168.1.1 -sV --version-lightLighter/faster detection (less reliable)
--version-allnmap 192.168.1.1 -sV --version-allFull (intensity 9) detection
-Anmap 192.168.1.1 -AIncludes -sV, OS detection, NSE scripts, traceroute

OS Detection

Fingerprint the target TCP/IP stack to guess the OS.

SwitchExampleDescription
-Onmap 192.168.1.1 -ORemote OS detection (TCP/IP fingerprinting)
--osscan-limitnmap 192.168.1.1 -O --osscan-limitSkip OS detection unless ports show open/closed pattern
--osscan-guessnmap 192.168.1.1 -O --osscan-guessBe more aggressive about guesses
--max-os-triesnmap 192.168.1.1 -O --max-os-tries 1Limit how many OS probe attempts are made
-Anmap 192.168.1.1 -AOS detection included with -A

Timing & Performance

Built-in timing templates trade off speed vs stealth.

SwitchExampleDescription
-T0nmap 192.168.1.1 -T0Paranoid β€” max IDS evasion (very slow)
-T1nmap 192.168.1.1 -T1Sneaky β€” IDS evasion
-T2nmap 192.168.1.1 -T2Polite β€” reduce bandwidth/CPU usage
-T3nmap 192.168.1.1 -T3Normal (default)
-T4nmap 192.168.1.1 -T4Aggressive β€” faster but noisier
-T5nmap 192.168.1.1 -T5Insane β€” assumes very fast, reliable network

Timing Tunables (Fine Control)

Adjust timeouts, parallelism, rates and retries.

  • --host-timeout <time> β€” give up on a host after this time (e.g., --host-timeout 2m).
  • --min-rtt-timeout, --max-rtt-timeout, --initial-rtt-timeout <time> β€” control probe RTT timeouts.
  • --min-hostgroup, --max-hostgroup <size> β€” group size for parallel host scanning.
  • --min-parallelism, --max-parallelism <num> β€” probe parallelization controls.
  • --max-retries <tries> β€” maximum retransmissions.
  • --min-rate <n> / --max-rate <n> β€” packet send rate bounds.

Examples:

nmap --host-timeout 4m --max-retries 2 192.168.1.1
nmap --min-rate 100 --max-rate 1000 -p- 192.168.1.0/24

NSE (Nmap Scripting Engine)

Use scripts to automate checks, fingerprinting, vulnerability discovery and enumeration.

SwitchExampleNotes
-sCnmap 192.168.1.1 -sCRun default safe scripts (convenient discovery)
--scriptnmap 192.168.1.1 --script http*Run scripts by name or wildcard
--script <script1>,<script2>nmap --script banner,http-titleRun specific scripts
--script-argsnmap --script snmp-sysdescr --script-args snmpcommunity=publicProvide args to scripts
--script "not intrusive"nmap --script "default and not intrusive"Compose script sets (example)

Useful NSE Examples

A few practical one-liners to keep handy.

# Generate sitemap from web server (HTTP):
nmap -Pn --script=http-sitemap-generator scanme.nmap.org

# Fast random search for web servers:
nmap -n -Pn -p 80 --open -sV -vvv --script banner,http-title -iR 1000

# Brute-force DNS hostnames (subdomain guessing):
nmap -Pn --script=dns-brute domain.com

# Safe SMB enumeration (useful on internal networks):
nmap -n -Pn -vv -O -sV --script smb-enum*,smb-ls,smb-mbenum,smb-os-discovery,smb-vuln* 192.168.1.1

# Whois queries via scripts:
nmap --script whois* domain.com

# Detect XSS-style unsafe output escaping on HTTP port 80:
nmap -p80 --script http-unsafe-output-escaping scanme.nmap.org

# Check for SQL injection (scripted):
nmap -p80 --script http-sql-injection scanme.nmap.org

Firewall / IDS Evasion & Spoofing

Techniques to make traffic less obvious. Use responsibly.

SwitchExampleDescription
-fnmap 192.168.1.1 -fFragment packets (can evade some filters)
--mtunmap 192.168.1.1 --mtu 32Set MTU/fragment size
-Dnmap -D decoy1,decoy2,ME,decoy3 targetDecoy IP addresses to confuse observers
-Snmap -S 1.2.3.4 targetSpoof source IP (may require raw sockets)
-gnmap -g 53 targetSet source port (useful to bypass simple filters)
--proxiesnmap --proxies http://192.168.1.1:8080 targetRelay scans through HTTP/SOCKS proxies
--data-lengthnmap --data-length 200 targetAppend random data to packets

Example IDS evasion command

nmap -f -T0 -n -Pn --data-length 200 -D 192.168.1.101,192.168.1.102,192.168.1.103,192.168.1.23 192.168.1.1

Output Formats & Options

Save scans so you can analyze later or process programmatically.

SwitchExampleDescription
-oNnmap 192.168.1.1 -oN normal.fileNormal human-readable output file
-oXnmap 192.168.1.1 -oX xml.fileXML output (good for parsing)
-oGnmap 192.168.1.1 -oG grep.fileGrepable output (legacy)
-oAnmap 192.168.1.1 -oA resultsWrite results.nmap, results.xml, results.gnmap
-oG -nmap 192.168.1.1 -oG -Print grepable to stdout
--append-outputnmap -oN file -append-outputAppend to an existing file
-v / -vvnmap -vIncrease verbosity
-d / -ddnmap -dIncrease debugging info
--reasonnmap --reasonShow reason a port state was classified
--opennmap --openShow only open or possibly-open ports
--packet-tracenmap --packet-traceShow raw packet send/receive detail
--iflistnmap --iflistList interfaces and routes
--resumenmap --resume results.fileResume an interrupted scan (requires prior save)

Helpful Output Examples & Pipelines

Combine Nmap with standard UNIX tools to extract actionable info.

# Find web servers (HTTP):
nmap -p80 -sV -oG - --open 192.168.1.0/24 | grep open

# Generate list of live hosts from random scan (XML -> grep -> cut):
nmap -iR 10 -n -oX out.xml | grep "Nmap" | cut -d " " -f5 > live-hosts.txt

# Append hosts from second scan:
nmap -iR 10 -n -oX out2.xml | grep "Nmap" | cut -d " " -f5 >> live-hosts.txt

# Compare two scans:
ndiff scan1.xml scan2.xml

# Convert XML to HTML:
xsltproc nmap.xml -o nmap.html

# Frequency of open ports (clean and aggregate):
grep " open " results.nmap | sed -r 's/ +/ /g' | sort | uniq -c | sort -rn | less

Miscellaneous Flags

SwitchExampleDescription
-6nmap -6 2607:f0d0:1002:51::4Enable IPv6 scanning
-hnmap -hShow help screen

Other Useful Commands (Mixed Examples)

# Discovery only on specific TCP ports, no port scan:
nmap -iR 10 -PS22-25,80,113,1050,35000 -v -sn

# ARP-only discovery on local net, verbose, no port scan:
nmap 192.168.1.0/24 -PR -sn -vv

# Traceroute to random targets (no ports):
nmap -iR 10 -sn --traceroute

# List targets only but use internal DNS server:
nmap 192.168.1.1-50 -sL --dns-server 192.168.1.1

# Show packet details during scan:
nmap 192.168.1.1 --packet-trace

Practical Tips & Etiquette

  • Always have written permission to scan networks you do not own.
  • Start small: discovery -> targeted port scan -> version detection -> scripts.
  • Use --script carefully; some scripts are intrusive.
  • Keep a log of what you scanned and when (timestamps help with audits).
  • For large networks, break scans into chunks and use --min-rate/--max-rate to control load.

Appendix β€” Quick Command Generator (Examples)

  • nmap -sS -p 1-100 -T4 -oA quick-scan 192.168.1.0/24 β€” fast SYN scan of top 100 ports, save outputs.
  • nmap -Pn -sV --script=vuln -oX vuln-check.xml 10.0.0.5 β€” skip host discovery, version & vulnerability scripts.

SSH Cheat Sheet

Whether you need a quick recap of SSH commands or you’re learning SSH from scratch, this guide will help. SSH is a must-have tool for network administrators and anyone who needs to log in to remote systems securely.


πŸ”‘ What Is SSH?

SSH (Secure Shell / Secure Socket Shell) is a network protocol that allows secure access to network services over unsecured networks.

Key tools included in the suite:

  • ssh-keygen β†’ Create SSH authentication key pairs.
  • scp (Secure Copy Protocol) β†’ Copy files securely between hosts.
  • sftp (Secure File Transfer Protocol) β†’ Securely send/receive files.

By default, an SSH server listens on TCP port 22.


πŸ“ Basic SSH Commands

CommandDescription
ssh user@hostConnect to remote server
ssh pi@raspberryConnect as pi on default port 22
ssh pi@raspberry -p 3344Connect on custom port 3344
ssh -i /path/file.pem admin@192.168.1.1Connect using private key file
ssh root@192.168.2.2 'ls -l'Execute remote command
ssh user@192.168.3.3 bash < script.shRun script remotely
ssh friend@Best.local "tar cvzf - ~/ffmpeg" > output.tgzDownload compressed directory

πŸ” Key Management

CommandDescription
ssh-keygenGenerate SSH keys
ssh-keygen -F [host]Find entry in known_hosts
ssh-keygen -R [host]Remove entry from known_hosts
ssh-keygen -y -f private.key > public.pubGenerate public key from private
ssh-keygen -t rsa -b 4096 -C "email@example.com"Generate new RSA 4096-bit key

πŸ“‚ File Transfers

SCP (Secure Copy)

CommandDescription
scp user@server:/file dest/Copy remote β†’ local
scp file user@server:/pathCopy local β†’ remote
scp user1@server1:/file user2@server2:/pathCopy between two servers
scp -r user@server:/folder dest/Copy directory recursively
scp -P 8080 file user@server:/pathConnect on port 8080
scp -CEnable compression
scp -vVerbose output

SFTP (Secure File Transfer)

CommandDescription
sftp user@serverConnect to server via SFTP
sftp -P 8080 user@serverConnect on port 8080
sftp -r dir user@server:/pathRecursively transfer directory

βš™οΈ SSH Configurations & Options

CommandDescription
man ssh_configSSH client configuration manual
cat /etc/ssh/ssh_configView system-wide SSH client config
cat /etc/ssh/sshd_configView system-wide SSH server config
cat ~/.ssh/configView user-specific config
cat ~/.ssh/known_hostsView logged-in hosts

SSH Agent & Keys

CommandDescription
ssh-agentStart agent to hold private keys
ssh-add ~/.ssh/id_rsaAdd key to agent
ssh-add -lList cached keys
ssh-add -DDelete all cached keys
ssh-copy-id user@serverCopy keys to remote server

πŸ–₯️ Remote Server Management

After logging into a remote server:

  • cd β†’ Change directory
  • ls β†’ List files
  • mkdir β†’ Create directory
  • mv β†’ Move/rename files
  • nano/vim β†’ Edit files
  • ps β†’ List processes
  • kill β†’ Stop process
  • top β†’ Monitor resources
  • exit β†’ Close SSH session

πŸš€ Advanced SSH Commands

X11 Forwarding (GUI Apps over SSH)

  • Client ~/.ssh/config:

    Host *
      ForwardAgent yes
      ForwardX11 yes
    
  • Server /etc/ssh/sshd_config:

    X11Forwarding yes
    X11DisplayOffset 10
    X11UseLocalhost no
    
CommandDescription
sshfs user@server:/path /local/mountMount remote filesystem locally
ssh -C user@hostEnable compression
ssh -X user@serverEnable X11 forwarding
ssh -Y user@serverEnable trusted X11 forwarding

πŸ”’ SSH Tunneling

Local Port Forwarding -L

ssh -L local_port:destination:remote_port user@server

Example: ssh -L 2222:10.0.1.5:3333 root@192.168.0.1

Remote Port Forwarding -R

ssh -R remote_port:destination:destination_port user@server

Example: ssh -R 8080:192.168.3.8:3030 -N -f user@remote.host

Dynamic Port Forwarding -D (SOCKS Proxy)

ssh -D 6677 -q -C -N -f user@host

ProxyJump -J (Bastion Host)

ssh -J user@proxy_host user@target_host

πŸ›‘οΈ Security Best Practices

  • Disable unused features: AllowTcpForwarding no, X11Forwarding no.
  • Change default port from 22 to something else.
  • Use SSH certificates with ssh-keygen.
  • Restrict logins with AllowUsers in sshd_config.
  • Use bastion hosts for added security.

βœ… Conclusion

This cheat sheet covered:

  • Basic SSH connections
  • File transfers (SCP/SFTP)
  • Key management & configs
  • Remote management commands
  • Advanced tunneling & forwarding

SSH remains an indispensable tool for IT professionals and security practitioners.

Wireshark Cheat Sheet

Wireshark is one of the most popular and powerful tools for capturing, analyzing, and troubleshooting network traffic.

Whether you are a network administrator, security professional, or just someone curious about how networks work, learning Wireshark is a valuable skill. This cheat sheet serves as a quick reference for filters, commands, shortcuts, and syntax.


πŸ“Š Default Columns in Packet Capture

NameDescription
No.Frame number from the beginning of the packet capture
TimeSeconds from the first frame
Source (src)Source address (IPv4, IPv6, or Ethernet)
Destination (dst)Destination address
ProtocolProtocol in Ethernet/IP/TCP segment
LengthFrame length in bytes

πŸ”Ž Logical Operators

OperatorDescriptionExample
and / &&Logical ANDAll conditions must match
or / ``Logical ORAt least one condition matches
xor / ^^Logical XOROnly one of two conditions matches
not / !NegationExclude packets
[n] [ ... ]Substring operatorMatch specific text

🎯 Filtering Packets (Display Filters)

OperatorDescriptionExample
eq / ==Equalip.dest == 192.168.1.1
ne / !=Not equalip.dest != 192.168.1.1
gt / >Greater thanframe.len > 10
lt / <Less thanframe.len < 10
ge / >=Greater or equalframe.len >= 10
le / <=Less or equalframe.len <= 10

🧩 Filter Types

NameDescription
Capture filterApplied during capture
Display filterApplied to hide/show after capture

πŸ“‘ Capturing Modes

ModeDescription
Promiscuous modeCapture all packets on the segment
Monitor modeCapture all wireless traffic (Linux/Unix only)

⚑ Miscellaneous

  • Slice Operator β†’ [ ... ] (range)
  • Membership Operator β†’ {} (in)
  • Ctrl+E β†’ Start/Stop capturing

πŸ” Capture Filter Syntax

Example:

tcp src 192.168.1.1 and tcp dst 202.164.30.1

🎨 Display Filter Syntax

Example:

http and ip.dst == 192.168.1.1 and tcp.port

⌨️ Keyboard Shortcuts (Main Window)

ShortcutAction
Tab / Shift+TabMove between UI elements
↓ / ↑Move between packets/details
Ctrl+↓ / F8Next packet (even if unfocused)
Ctrl+↑ / F7Previous packet
Ctrl+.Next packet in conversation
Ctrl+,Previous packet in conversation
Return / EnterToggle tree item
BackspaceJump to parent node

πŸ“‘ Protocol Values

ether, fddi, ip, arp, rarp, decnet, lat, sca, moprc, mopdl, tcp, udp

πŸ” Common Filtering Commands

UsageSyntax
Filter by IPip.addr == 10.10.50.1
Destination IPip.dest == 10.10.50.1
Source IPip.src == 10.10.50.1
IP rangeip.addr >= 10.10.50.1 and ip.addr <= 10.10.50.100
Multiple IPsip.addr == 10.10.50.1 and ip.addr == 10.10.50.100
Exclude IP!(ip.addr == 10.10.50.1)
Subnetip.addr == 10.10.50.1/24
Porttcp.port == 25
Destination porttcp.dstport == 23
IP + Portip.addr == 10.10.50.1 and tcp.port == 25
URLhttp.host == "hostname"
Timeframe.time >= "June 02, 2019 18:04:00"
SYN flagtcp.flags.syn == 1 and tcp.flags.ack == 0
Beacon frameswlan.fc.type_subtype == 0x08
Broadcasteth.dst == ff:ff:ff:ff:ff:ff
Multicast(eth.dst[0] & 1)
Hostnameip.host == hostname
MAC addresseth.addr == 00:70:f4:23:18:c4
RST flagtcp.flag.reset == 1

πŸ› οΈ Main Toolbar Items

IconItemMenuDescription
▢️StartCapture β†’ StartBegin capture
⏹️StopCapture β†’ StopStop capture
πŸ”„RestartCapture β†’ RestartRestart session
βš™οΈOptionsCapture β†’ Options…Capture options dialog
πŸ“‚OpenFile β†’ Open…Load capture file
πŸ’ΎSave AsFile β†’ Save As…Save capture file
❌CloseFile β†’ CloseClose current capture
πŸ”„ReloadView β†’ ReloadReload capture file
πŸ”Find PacketEdit β†’ Find Packet…Search packets
βͺGo BackGo β†’ BackJump back in history
⏩Go ForwardGo β†’ ForwardJump forward
πŸ”Go to PacketGo β†’ PacketJump to specific packet
↩️First PacketGo β†’ First PacketJump to first packet
β†ͺ️Last PacketGo β†’ Last PacketJump to last packet
πŸ“œAuto ScrollView β†’ Auto ScrollScroll live capture
🎨ColorizeView β†’ ColorizeColorize packet list
πŸ”ŽZoom In/OutView β†’ Zoom In/OutAdjust zoom level
πŸ”²Normal SizeView β†’ Normal SizeReset zoom
πŸ“Resize ColumnsView β†’ Resize ColumnsFit column width

βœ… Conclusion

Wireshark is an incredibly powerful tool for analyzing and troubleshooting network traffic. This cheat sheet gives you commands, filters, and shortcuts to navigate Wireshark efficiently and quickly.