If you like my tips, buy me a coffee
I believe that it is my responsibility to transfer the knowledge I gathered through the years of my experience with Linux
To copy all from folder A on server 1 to folder B on server 2 using SSH
ssh username1@server1 -p <port>
run the following command on server 1
scp -r -P <port> /folderpath/A/ username2@server2:/folderpath/B/
Zipping a folder, including sub-folders and hidden files
zip -r yourzipfile.zip folder/* .*
CSF commands
csf -g [IP ADDRESS] will check for any IP blocks
csf -tr [IP ADDRESS] will remove a temporary block
csf -dr [IP ADDRESS] will remove a permanent block
To find a string in some files in some folder (in my case finding the string 'pane-toggle' in the folder web1)
grep --color -r -i -n -w 'pane-toggler' web1/
Options explanation:
--color : nice colorful output ;)
-r : recursive... process the directory and subdirectories
-i : ignore case of letter... not like DOS/windows. I linux, grep will follow you instruction. So if you want to find 'Red' and 'red', use -i
-n : shows the line number in the file where the string exists
-w : will find only matches of whole word, i.e. if you are looking for 'pencil' not pencils', use -w
Backup MySQL database using mysqldump tool:
sudo mysqldump -h <host_name/IP> --column-statistics=0 --single-transaction --set-gtid-purged=OFF -u <user_name> -p <database_name> | gzip > <file_name>_$(date +%F.%H%M%S).sql.gz
Mysql Backup
mysqldump -u root -p[root_password] [database_name] > dumpfilename.sql
Mysql Restore
mysql -u root -p[root_password] [database_name] < dumpfilename.sql
Mysql Purge Binary Logs
mysql> PURGE BINARY LOGS BEFORE '2009-05-01 00:00:00';
This command will list the 15 largest in order:
du -xhS | sort -h | tail -n15
How to get size of a MySQL database
Size in GB
SELECT table_schema "DB Name",
ROUND(SUM(data_length + index_length) / 1024 / (1024*1024), 1) "DB Size in GB"
FROM information_schema.tables
GROUP BY table_schema;
Size in MB
SELECT table_schema "DB Name",
ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) "DB Size in GB"
FROM information_schema.tables
GROUP BY table_schema;
Replace URL in .SQL/TEXT file
sed -i 's,http://www.find.com/page,http://www.replace.com/page,g' <file name>
Resize filesystem partition size without loosing data using command line, using fdisk tool
Important notes:
Always backup your important data before performing this act (skip this if you are just playing around linux)
Examples provided here maybe different in your case, so be careful
Steps:
Get the Hard disk name using the command df -h /
Example: (Harddisk /dev/sda)
~$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 7.4G 2.0G 80% /
~$
Get the Partition name using the command lsblk
Example: (Partition sda2 or 2)
~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 99.4M 1 loop /snap/core/11316
loop1 7:1 0 99.4M 1 loop /snap/core/11187
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1M 0 part
└─sda2 8:2 0 10G 0 part /
sr0 11:0 1 1024M 0 rom
~$
(STOP! Is the data on the hard disk important? Make sure you have a backup of it)
Run the command sudo fdisk /dev/sda
If you get an error "GPT PMBR size mismatch (41943039 != 62914559) will be corrected by w(rite)."
Fdisk used to not work at all on gpt partitioned drives, it just reported that drive was gpt partitioned. Better to use parted, gparted or gdisk. Gdisk has been the command line tool for gpt drives.
Post these:
sudo parted -l
or
sudo parted /dev/sda unit s print
or
sudo gdisk -l /dev/sda
Example:
~$sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p # print the partition table
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: ########-####-####-####-#############
Device Start End Sectors Size Type
/dev/sda1 2048 4095 2048 1M BIOS boot
/dev/sda2 4096 20969471 20965376 10G Linux filesystem
Command (m for help): d # delete a partition
Partition number (1,2, default 2): 2 # partition number
Partition 2 has been deleted.
Command (m for help): n # add a new partition
Partition number (2-128, default 2): 2 # partition number
First sector (4096-41943006, default 4096): # Make sure you same number of Start
Last sector, +sectors or +size{K,M,G,T,P} (4096-41943006, default 41943006): # Use the default value to use the MAX available size for extending
Created a new partition 2 of type 'Linux filesystem' and of size 20 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N # Don't remove the old signature, else you will loose your data!
Command (m for help): w # write table to disk and exit (If you have any doubts, type q now!)
The partition table has been altered.
Syncing disks.
~$
Run the command sudo resize2fs /dev/sda2
Example:
~$ sudo resize2fs /dev/sda2
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 3
The filesystem on /dev/sda2 is now 5242363 (4k) blocks long.
~$
Copy folder content except one folder
Important notes:
If you have a folder /home/user1/public_html/app and you want to copy all the content of this folder with all files and directories except one directory /home/user1/public_html/app/large_files
We are assuming you have a folder /home/user1/public_html/app, and you want to copy all content of this folder except a folder called large_files
Examples provided here maybe different in your case, so be careful
Steps:
Get the Hard disk name using the command df -h /
Example: (Harddisk /dev/sda)
~$ df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 9.8G 7.4G 2.0G 80% /
~$
Get the Partition name using the command lsblk
Example: (Partition sda2 or 2)
~$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 99.4M 1 loop /snap/core/11316
loop1 7:1 0 99.4M 1 loop /snap/core/11187
sda 8:0 0 20G 0 disk
├─sda1 8:1 0 1M 0 part
└─sda2 8:2 0 10G 0 part /
sr0 11:0 1 1024M 0 rom
~$
(STOP! Is the data on the hard disk important? Make sure you have a backup of it)
Run the command sudo fdisk /dev/sda
Example:
~$sudo fdisk /dev/sda
Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.
Command (m for help): p # print the partition table
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: ########-####-####-####-#############
Device Start End Sectors Size Type
/dev/sda1 2048 4095 2048 1M BIOS boot
/dev/sda2 4096 20969471 20965376 10G Linux filesystem
Command (m for help): d # delete a partition
Partition number (1,2, default 2): 2 # partition number
Partition 2 has been deleted.
Command (m for help): n # add a new partition
Partition number (2-128, default 2): 2 # partition number
First sector (4096-41943006, default 4096): # Make sure you same number of Start
Last sector, +sectors or +size{K,M,G,T,P} (4096-41943006, default 41943006): # Use the default value to use the MAX available size for extending
Created a new partition 2 of type 'Linux filesystem' and of size 20 GiB.
Partition #2 contains a ext4 signature.
Do you want to remove the signature? [Y]es/[N]o: N # Don't remove the old signature, else you will loose your data!
Command (m for help): w # write table to disk and exit (If you have any doubts, type q now!)
The partition table has been altered.
Syncing disks.
~$
Run the command sudo resize2fs /dev/sda2
Example:
~$ sudo resize2fs /dev/sda2
resize2fs 1.44.1 (24-Mar-2018)
Filesystem at /dev/sda2 is mounted on /; on-line resizing required
old_desc_blocks = 2, new_desc_blocks = 3
The filesystem on /dev/sda2 is now 5242363 (4k) blocks long.
~$
Steps I ran: (Used with Logical Volume)
Run below command to get PV (Physical Volume) name (Ex: /dev/sda1)
sudo pvs
Resize the PV (Ex: sudo pvresize /dev/sda1)
sudo pvresize <PV name from above step>
Run below command to get root logical volume name (Filesystem value of / row; ex: /dev/mapper/ubuntu--vg-root)
df -h
Expand logical volume (ex : sudo lvextend -r -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv):
sudo lvextend -r -l +100%FREE <root logical volume name from above step>
Fixed EXIM Error : all hosts for 'domain.tld' have been failing for a long time (and retry time not reached)
In most situations this error It occurs when database "Exim Retry" It is corrupt. So the problem is The server that is trying to send the message.
resolving error consists Exim delete Retry Database si restartEXIM service area server.
Perform the following server command line to delete database Exim Relay:
cd /var/spool/exim/db
rm -f retry retry.lockfile
rm -f wait-remote_smtp wait-remote_smtp.lockfile
After executing these commands, the files will be deleted: retry, retry.lockfile, wait-remote_smtp and wait-remote_smtp.lockfile, restartyou have the "exim" service.
service exim restart
To execute these commands you must have access to the server console (or SSH access) and sufficient permissions.
How do I run a single command at startup using systemd?
You can see a list of all services using the command below:
systemctl list-units --type=service
For now, you can start creating a unit file here and then finally when it is done move it to /etc/systemd/system the directory. Creating a unit file with the name of your service:
$ touch <service name>.service
File content:
[Unit]
Description=<service description>
After=network.target
[Service]
Type=simple
ExecStart=<command>
WorkingDirectory=<path>
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
[Install]
WantedBy=multi-user.target
Load/enable/start as service:
$ sudo systemctl daemon-reload
$ sudo systemctl enable <service name>.service
$ sudo systemctl start <service name>.service
Reset a MySQL root password
You must have linux root to reset the MySQL root password.
Stop the MySQL service
sudo /etc/init.d/mysql stop
Start MySQL without a password
sudo mysqld_safe --skip-grant-tables &
Connect to MySQL
mysql -uroot
Remove MySQL root password
use mysql;
update user set authentication_string=null where User='root';
flush privileges;
quit
Stop and start the MySQL service
sudo /etc/init.d/mysql stop
...
sudo /etc/init.d/mysql start
Log in to the database and set a new root password for MySQL
mysql -u root
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('strong password');
flush privileges;
How to Install Webmin on Ubuntu 24.04 (step by step)
Deploy a Ubuntu 24.04 server instance on your server
Create a new subdomain DNS record pointing to your server IP address. For example, webmin.example.com
Access the server using SSH as a non-root user with sudo privileges
sudo curl -o setup-repos.sh https://raw.githubusercontent.com/webmin/webmin/master/setup-repos.sh; sudo bash setup-repos.sh
sudo bash setup-repos.sh
sudo apt install --install-recommends webmin -y
sudo systemctl status webmin
sudo ufw allow 80/tcp
sudo apt install certbot -y
sudo certbot certonly --standalone -d webmin.example.com -m webmin@example.com --agree-tos
sudo cat /etc/letsencrypt/live/webmin.example.com/fullchain.pem /etc/letsencrypt/live/webmin.example.com/privkey.pem > webmin.pem
sudo mv webmin.pem /etc/webmin/
sudo nano /etc/webmin/miniserv.conf
keyfile=/etc/webmin/webmin.pem
sudo systemctl restart webmin
sudo ufw allow 10000
sudo nano /etc/webmin/miniserv.conf
sudo ufw reload
sudo ufw reload
https://webmin.example.com:10000
source: https://docs.vultr.com/how-to-install-webmin-on-ubuntu-24-04
List of useful commands to manage ( exim ) mail server
Display the number of email messages in the queue
exim -bpc
Display information about email messages in the queue
exim -bp
Displays time queued, size, message-id, sender and recipient.
Display a summary of messages in the queue
exim -bp | exiqsumm
Displays count, volume, oldest, newest, domain, and totals.
Display Exim’s current activity
exiwhat
Test Exim SMTP transaction
exim -bh ipaddress
This spoofs an SMTP transaction emanating from ipaddress. Exim’s status will be displayed as the transaction runs. Note: the message will not be delivered.
Display Exim settings
exim -bP
Search the mail queue for messages from a specific sender
exiqgrep -f [luser]@domain
Search the mail queue for messages from a specific recipient or domain
exiqgrep -r [luser]@domain
Display messages older than a specified number of seconds
exiqgrep -o seconds [...]
Display messages newer than a specified number of seconds
exiqgrep -y seconds [...]
Locate messages matching a specific size
exiqgrep -s '^4..$' [...]
For example, 400-499 bytes.
Use -z to match only frozen messages.
Use -x to match only unfrozen messages.
To display just the message-id, use -I.
-c shows the message count.
Display the message count of the mail queue
exiqgrep -c ...
Start a queue run
exim -q -v
Start a queue run isolated to local deliveries
exim -ql -v
Remove a message from the queue
exim -Mrm <message-id> [ <message-id> ... ]
Freeze a message
exim -Mf <message-id> [ <message-id> ... ]
Throw a message
exim -Mt <message-id> [ <message-id> ... ]
Deliver a message
exim -M <message-id> [ <message-id> ... ]
Deliver a message (if the retry time has been reached)
exim -Mc <message-id> [ <message-id> ... ]
Force a message to fail
exim -Mg <message-id> [ <message-id> ... ]
Remove all frozen messages
exiqgrep -z -i | xargs exim -Mrm
Remove all messages older than a defined number of seconds
exiqgrep -o seconds -i | xargs exim -Mrm
Freeze all queued mail from a named sender
exiqgrep -i -f luser@example.net| xargs exim -Mf
View a message’s mail headers
exim -Mvh <message-id>
View a message’s body
exim -Mvb <message-id>
View a message’s logs
exim -Mvl <message-id>
Add a recipient to a message
exim -Mar <message-id> <address> [ <address> ... ]
Edit a message sender
exim -Mes <message-id> <address>
Creating a LAMP container on PROXMOX - use it SMTP testing tool
Create a CT from the ubuntu CT Templates.
Start and Login to the CT
Run this line:
apt update && apt install apache2 php php-mysql php-curl php-cli php-xml php-mbstring php-zip php-gd php-bcmath mysql-server -y
Run it in the folder /var/www/html
composer require phpmailer/phpmailer
Create index.php and paste the code below in it
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
require 'vendor/autoload.php';
$message = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$smtp_host = $_POST['smtp_host'] ?? '';
$smtp_port = $_POST['smtp_port'] ?? '';
$smtp_user = $_POST['smtp_user'] ?? '';
$smtp_pass = $_POST['smtp_pass'] ?? '';
$smtp_secure = $_POST['smtp_secure'] ?? '';
$from_email = $_POST['from_email'] ?? '';
$from_name = $_POST['from_name'] ?? '';
$to_email = $_POST['to_email'] ?? '';
$subject = $_POST['subject'] ?? '';
$body = $_POST['body'] ?? '';
$mail = new PHPMailer(true);
try {
// SMTP configuration
$mail->isSMTP();
$mail->Host = $smtp_host;
$mail->SMTPAuth = true;
$mail->Username = $smtp_user;
$mail->Password = $smtp_pass;
$mail->SMTPSecure = $smtp_secure ?: PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = (int)$smtp_port;
// Sender & Recipient
$mail->setFrom($from_email, $from_name);
$mail->addAddress($to_email);
// Email content
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = nl2br($body);
$mail->AltBody = strip_tags($body);
// Send email
$mail->send();
$message = '<div style="color: green;">✅ Email sent successfully!</div>';
} catch (Exception $e) {
$message = '<div style="color: red;">❌ Mailer Error: ' . htmlspecialchars($mail->ErrorInfo) . '</div>';
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SMTP Mailer</title>
<style>
body {
font-family: Arial, sans-serif;
background: #f2f5f8;
margin: 0;
padding: 0;
}
.container {
max-width: 750px;
margin: 50px auto;
background: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
}
h2 {
text-align: center;
color: #333;
margin-bottom: 25px;
}
label {
display: block;
margin-top: 12px;
font-weight: bold;
color: #333;
}
input, textarea, select {
width: 100%;
padding: 10px;
margin-top: 6px;
border: 1px solid #ccc;
border-radius: 6px;
font-size: 14px;
}
textarea {
resize: vertical;
}
button {
width: 100%;
margin-top: 25px;
background: #007BFF;
color: #fff;
border: none;
padding: 12px;
border-radius: 6px;
font-size: 16px;
cursor: pointer;
}
button:hover {
background: #0056b3;
}
.message {
margin-top: 20px;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h2>Send Email via Authenticated SMTP</h2>
<form method="POST" action="">
<h3>SMTP Configuration</h3>
<label>SMTP Host:</label>
<input type="text" name="smtp_host" placeholder="smtp.example.com" required>
<label>SMTP Port:</label>
<input type="number" name="smtp_port" value="587" required>
<label>SMTP Username:</label>
<input type="text" name="smtp_user" placeholder="your_email@example.com" required>
<label>SMTP Password:</label>
<input type="password" name="smtp_pass" placeholder="Your SMTP password" required>
<label>Encryption Type:</label>
<select name="smtp_secure">
<option value="tls" selected>TLS (Port 587)</option>
<option value="ssl">SSL (Port 465)</option>
<option value="">None</option>
</select>
<h3>Sender & Recipient</h3>
<label>From Email:</label>
<input type="email" name="from_email" placeholder="your_email@example.com" required>
<label>From Name:</label>
<input type="text" name="from_name" placeholder="Your Name" required>
<label>To (Recipient Email):</label>
<input type="email" name="to_email" placeholder="recipient@example.com" required>
<h3>Message</h3>
<label>Subject:</label>
<input type="text" name="subject" placeholder="Subject" required>
<label>Body:</label>
<textarea name="body" rows="6" placeholder="Type your message..." required></textarea>
<button type="submit">Send Email</button>
</form>
<div class="message"><?= $message ?></div>
</div>
</body>
</html>
Save the file and point your browser to your CT IP
Leave a comment below if you need more information