Install Zabbix on Linux server

Zabbix is an open-source monitoring software tool for diverse IT components, including networks, servers, virtual machines (VMs), and cloud services. Zabbix is able to monitor a lot of things, also provides a single pane of glass view of your whole IT infrastructure.

Configure the Zabbix repository.

yum install -y centos-release-scl

Install the Zabbix repository configuration package.

rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm

Install Zabbix Server.

yum install -y zabbix-web-mysql-scl zabbix-apache-conf-scl zabbix-server-mysql zabbix-agent --enablerepo=zabbix-frontend

Change timezone.

vi /etc/opt/rh/rh-php72/php-fpm.d/zabbix.conf
php_value[date.timezone] = America/Vancouver

Install MySQL or MariaDB.

yum install -y mariadb-server mariadb

Start mariadb service.

systemctl start mariadb
systemctl status mariadb

Login to MariaDB and create the database and user for our Zabbix installation.

mysql -u root -p

Create a database with information eblow.

DBName:zabbixdb
DBUser: zabbixuser
DBPassword:123456

MariaDB [(none)]> create database zabbixdb character set utf8 collate utf8_bin;
MariaDB [(none)]> grant all privileges on zabbixdb.* to zabbixuser@localhost identified by '123456';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> exit

Import initial schema and database.

cd /usr/share/doc/zabbix-server-mysql*/
zcat create.sql.gz | mysql -u zabbixuser -p zabbixdb

Update Database Configuration

Edit the zabbix_server.conf file.

DBHost=localhost
DBName=zabbixdb
DBUser=zabbixuser
DBPassword=123456

Restart Zabbix service.

systemctl restart zabbix-server zabbix-agent httpd rh-php72-php-fpm

Enable the service to start automatically on system reboot.

systemctl enable zabbix-server zabbix-agent httpd rh-php72-php-fpm

Disable SELinux.

sudo setenforce 0

Allow Zabbix services on Firewall.

firewall-cmd --permanent --add-port=10050/tcp
firewall-cmd --permanent --add-port=10051/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd –reload

Setup Zabbix via a web interface.

http://10.0.0.134/zabbix/

Enter zabbixdb, zabbixuser and password.

Zabbix Dashboard.

Username: Admin (Username is case sensitive.)

Passwordzabbix

Zabbix Dashboard.

Check ports are used on the Zabbix server.
netstat -antp | grep "LISTEN"

Install HTTPS web certificate on the Zabbix web interface.

Install mod security.

yum install mod_ssl -y

Copy web server certificate (used wildcard cert *.linuxlab.local) to Zabbix server.

Edit ssl.conf file.

vi /etc/httpd/conf.d/ssl.conf
#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/pki/tls/certs/wildcard.crt
#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/pki/tls/certs/wildcard-cert.key
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
SSLCertificateChainFile /etc/pki/CA/certs/ourCA.crt

Restart Apache web service.

systemctl restart httpd
systemctl status httpd

Allow HTTPS on Firewall.

firewall-cmd --permanent --add-service=https
firewall-cmd --reload

Access Zabbix server from Windows machine.

https://zabbix.linuxlab.local/zabbix/

Redirect HTTP to HTTPS on Apache by using .htaccess file.

cd /etc/httpd/conf.modules.d/
cat 00-base.conf | grep rewrite
cd /usr/share/zabbix/
touch .htaccess
vi .htaccess
###---
RewriteEngine On
RewriteCond %{HTTPS}  !=on
#RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
RewriteRule ^/?(.*) https://zabbix.linuxlab.local/$1 [R,L]

Access Zabbix via HTTP. It will redirect the link to HTTPS.

Install Graylog open-source log management on Linux server

Graylog is an open-source log management system. Graylog centrally captures, collects, enhances, stores, and analyzes log data. It is an affordable alternative to Splunk.

Below are a couple of steps to install Graylog on CentOS 7.

Edit interface, change ONBOOT from “no” to “yes”, and restart network service.

Step #1: Update your system and install needed packages.

hostnamectl set-hostname graylog
yum update -y
yum install epel-release
yum install pwgen vim

Step #2: Install JAVA

yum install java-1.8.0-openjdk-headless.x86_64

Check the java version.

java -version

Create a repository file. Then add the content below to this repository.

vim /etc/yum.repos.d/mongodb-org.repo
--
[mongodb-org-4.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.2.asc

Install MongoDB

yum install mongodb-org

Enable and start mongoDB service on system.

sudo systemctl daemon-reload
sudo systemctl enable mongod.service
sudo systemctl start mongod.service
sudo systemctl --type=service --state=active | grep mongod

Check MongoDB service port.

netstat -antp | grep 27017

Step #4: Installing Elasticsearch

Graylog can be used with Elasticsearch 6x, 7.x, In this lab, I have used version 6x of Elasticsearch.

Install the Elastic GPG key.

rpm –import https://artifacts.elastic.co/GPG-KEY-elasticsearch

Create a repository, then add the following contents to the file.

vim /etc/yum.repos.d/elasticsearch.repo

[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/oss-6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

Install the open-source version of Elasticsearch.

yum install elasticsearch-oss

Modify the Elasticsearch configuration file. Set the cluster name to graylog and add “action.auto_create_index: false” to the file.

vim /etc/elasticsearch/elasticsearch.yml

Save and exit the file.

Enable, start and check the status of elastic search on the system.

sudo systemctl daemon-reload
sudo systemctl enable elasticsearch.service
sudo systemctl restart elasticsearch.service
sudo systemctl --type=service --state=active | grep elasticsearch

Check elastic search health.

curl -XGET 'http://localhost:9200/_cluster/health?pretty=true'

Step #5: Installing the Graylog

Now install the Graylog repository configuration with the following commands:

rpm -Uvh https://packages.graylog2.org/repo/packages/graylog-4.2-repository_latest.rpm

Install Graylog-server.

yum install graylog-server

Configure Graylog:

Add “password_secret” and “root_password_sha2” to server.conf file.

Generate password_secret.

pwgen -N 1 -s 96

Generate root_password_sha2.

echo -n foss@dan123 | sha256sum | cut -d” ” -f1

Edit etc/graylog/server/server.conf file.

vim /etc/graylog/server/server.conf

Uncomment the following line.

http_bind_address = 127.0.0.1:9000

and add http_bind_address = 10.0.0.33:9000

Enable and Start service.

systemctl enable graylog-server.service
systemctl start graylog-server.service

Monitor server logs.

tail -f /var/log/graylog-server/server.log

Copy Geo-IP database to Graylog server.

Check log again.

Check Graylog Server listening port.

netstat -antp | grep 9000

Check the port is opened on a remote host.

Allow Graylog service on Firewall.

Access Graylog web interface on another machine.

Check Windows Defender status on a Windows computer

According to Microsoft, (https://www.microsoft.com/security/blog/2021/05/11/gartner-names-microsoft-a-leader-in-the-2021-endpoint-protection-platforms-magic-quadrant/), Microsoft Windows Defender becomes a Leader in the 2021 Endpoint Protection Platforms Magic Quadrant.

Checking Windows Defender status on a Windows computer.

Get-MpComputerStatus | Select-Object -Property Antivirusenabled,AMServiceEnabled,AntispywareEnabled,BehaviorMonitorEnabled,IoavProtectionEnabled,NISEnabled,OnAccessProtectionEnabled,RealTimeProtectionEnabled,AntivirusSignatureLastUpdate
PS script to check Windows Defender service on Windows domain-joined machine.
[CmdletBinding()]
 
Param
(
    [Parameter(Mandatory=$false,
                ValueFromPipelineByPropertyName=$true,
                ValueFromPipeline=$true
                )]
    [string[]]$ComputerName = $env:COMPUTERNAME
)

$result=@()
$ErrorActionPreference="SilentlyContinue"

$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Query Windows 10 domain-joined on Active Directory
$computername = (Get-ADComputer -filter {OperatingSystem -Like '*Windows 10*'}).name
foreach($computer in $computername){
    $ping_result = Test-Connection -ComputerName $computer -Count 1 -Quiet
        if($ping_result){
        $result=Invoke-Command -ComputerName $computer {Get-MpComputerStatus | Select-Object -Property Antivirusenabled,AMServiceEnabled,AntispywareEnabled,BehaviorMonitorEnabled, `
        IoavProtectionEnabled,NISEnabled,OnAccessProtectionEnabled,RealTimeProtectionEnabled,AntivirusSignatureLastUpdated}
        }
        If ($result) {
                     $result+=New-Object -TypeName PSObject -Property ([ordered]@{
                    'Computer'=$result.PSComputername
                    'AntiVirusStatus'=$result.AntivirusEnabled
                    'AV Update'=$result.AntivirusSignatureLastUpdated
                    'Anti-Malware'=$result.AMServiceEnabled
                    'Anti-Spyware'=$result.AntispywareEnabled
                    'Behavior Monitor'=$result.BehaviorMonitorEnabled
                    'Office-Anti-Virus'=$result.IoavProtectionEnabled
                    'NIS'=$result.NISEnabled
                    'AccessProtection'=$result.OnAccessProtectionEnabled
                    'RelatimeProtection'=$result.RealTimeProtectionEnabled
                    })
                    }
}
Write-Output $result_WD

Run the PS script.

PowerShell commands and notes

PowerShell commands and notes:

#Recursive file search using PowerShell
Get-ChildItem -Path C:\ -Filter *Graylog* -Recurse -ErrorAction SilentlyContinue -Force
#checkdate in the last 24 hours
$checkdate = (Get-Date).AddHours(-24)
#check all files have been modified in the last 24 hours and output file name, size and the time was last modified
Get-ChildItem -Path C:\Shared -file -Recurse | Where-Object {$_.LastWriteTime -ge $checkdate} | Select-Object -Property Fullname,Length,LastWriteTime
#checkdate in the last 90days
$checkdate = (Get-Date).AddDays(-90)
#check files on the  C:\users\Administrator\Downloads directory and at least 100MB in size and LastWriteTime is less than $checkdate. Then output the result to csv file.
$files = Get-ChildItem -Path C:\users\Administrator\Downloads -file -Recurse |
Where-Object {$_.length -ge 100MB -AND $_.LastWriteTime -le $checkdate} |
Select Fullname,Length,CreationTime,LastWriteTime |
Export-CSV -Path myfiles-90days_100MB.csv

Check WinRM service is running on a remote host.

Test-NetConnection -ComputerName WIN10NEW11 -Port 5985 -WarningAction SilentlyContinue
#shows the last computer name started, running.
get-CimInstance -ClassName win32_operatingsystem -ComputerName $env:computername | Select-Object -property PSComputerName, LastBootUpTime, {(Get-Date) - $_.lastbootuptime}

Get Antivirus Product is installed and its status with PowerShell.

Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct

List the user accounts in the local administrator group in a Windows machine.

Get-CimInstance win32_group -filter "name = 'administrators' AND LocalAccount = 'true'" | Get-CimAssociatedInstance -ResultClassName win32_useraccount

List all installed software that has a name defined in a Windows machine.

Get-CimInstance win32_product -filter "name like '%'" | Select-Object -property Name,Vendor,Version,Description,InstallDate

Check if Wordpad is running, kills the Wordpad process, and then creates a sample text file that includes the current date that kills the process.

(Get-Process wordpad -ea silentlycontinue) -and (stop-process -name wordpad) -and ("$(Get-Date) killed wordpad") | Out-file C:\Shared\wordpadlog.txt

Search any files that have file extension is .srt on D:\Shared folder, then remove them.

Check before removing.
PS D:\Get-Childitem -path "D:\Shared" -Filter *.srt -Recurse -ErrorAction SilentlyContinue -Force | Remove-Item -Force -Whatif


PS D:\Get-Childitem -path "D:\Shared" -Filter *.srt -Recurse -ErrorAction SilentlyContinue -Force | Remove-Item -Force

Install IIS Web server via PS.

Add-WindowsFeature Web-Server, Web-WebServer, Web-Common-Http, Web-Default-Doc, Web-Dir-Browsing, Web-Http-Errors, Web-Static-Content, Web-Health, Web-Http-Logging, Web-Log-Libraries, Web-Request-Monitor, Web-Performance, Web-Stat-Compression, Web-Security, Web-Filtering, Web-Windows-Auth, Web-App-Dev, Web-Net-Ext45, Web-Asp-Net45, Web-ISAPI-Ext, Web-ISAPI-Filter, Web-Mgmt-Tools, Web-Mgmt-Console, Web-Mgmt-Compat, Web-Metabase, NET-Framework-45-Features, NET-Framework-45-Core, NET-Framework-45-ASPNET, NET-WCF-Services45, NET-WCF-HTTP-Activation45, NET-WCF-TCP-PortSharing45, WAS, WAS-Process-Model, WAS-Config-APIs -restart

Install Active Directory module via PS.

Import-Module ServerManager
Add-WindowsFeature -Name "RSAT-AD-PowerShell" –IncludeAllSubFeature

# Check the installation status of a module
Get-WindowsFeature RSAT-AD-PowerShell

Shut down and Restart Windows machine.

# Stop-Computer -Force -WhatIf
Stop-Computer -Force
# Restart-Computer -Force -WhatIf
Restart-Computer -Force
# Delay restart on 5 seconds
Start-Sleep -Seconds 5 ; Restart-Computer -Force
# Restart machine remotely
Restart-Computer -ComputerName PC1 -Force
# Restart-Computer (Multiple Windows 10 domain joined clients)

(Get-ADComputer -Filter 'operatingsystem -notlike "*server*"').Name | Restart-Computer -Force -ErrorAction silentlycontinue

Get, stop and start Windows services.

Get-Service
# search Windows updates service.
Get-Service | where-object {$_.name -like "*wuauserv*"}
# Start Windows updates service.
Start-Service wuauserv -PassThru
# Stop Windows updates service.
Stop-Service wuauserv -PassThru
# Get Windows updates status
Get-Service -name wuauserv
# Change statustype 
Set-Service -name wuauserv -StartupType Disabled -Status Stopped

Deploy Ublock Origin Ad blocker via a GPO

According to (https://github.com/gorhill/uBlock), Ublock Origin is an efficient blocker add-on for various browsers. Fast, potent, and lean. uBlock Origin is NOT an “ad blocker”: it is a wide-spectrum blocker — which happens to be able to function as a mere “ad blocker”. The default behavior of uBlock Origin when newly installed is to block ads, trackers, and malware sites.

+ Create a central store for GPO

Copies Chrome, Firefox, MS Edge Policy templates under C:\Windows\SYSVOL\sysvol\cisalab.local\Policies\PolicyDefinitions (copy to C:\Windows\SYSVOL\sysvol rather than \\SERVER\SYSVOL folder)

Google Chrome:

https://support.google.com/chrome/a/answer/187202?hl=en#zippy=%2Cwindows

Firefox:

https://support.mozilla.org/en-US/kb/customizing-firefox-using-group-policy-windows

MS Edge:

https://www.microsoft.com/en-us/edge/business/download

+ Create a new Ublock Origin GPO.

+ Configure UBlock Origin GPO.

Google Chrome. Control which extensions are installed silently – Enabled cjpalhdlnbpafiamejdnhcphjbkeiagm;https://clients2.google.com/service/update2/crx

Firefox:

Extensions to Install – Enabled

https://addons.mozilla.org/firefox/downloads/file/3886236/ublock_origin-1.40.2-an+fx.xpi

MS Edge:

Control which extensions are installed silently – Enabled odfafepnkmbhccpbejgmiehpchacaeak;https://edge.microsoft.com/extensionwebstorebase/v1/crx

+ Link UBlock Origin GPO to Domain computers group.

+ Restart Windows 10 domain-joined client to test.

Ublock Origin has been installed automatically on Windows 10 domain clients.

Get Current Windows OS build version

This is a PS code to get the current Windows OS build version. It is based on (“https://smsagent.blog/2017/05/18/find-the-full-windows-build-number-with-powershell/”)


Function Get-WindowsVersion{

[CmdletBinding()]

Param
(
    [Parameter(Mandatory=$false,
                ValueFromPipelineByPropertyName=$true,
                ValueFromPipeline=$true
                )]
    [string[]]$ComputerName = $env:COMPUTERNAME
)

Begin
{
    $Table = New-Object System.Data.DataTable
    $Table.Columns.AddRange(@("ComputerName","Windows Edition","Version","OS Build"))
}
Process
{
    Foreach ($Computer in $ComputerName)
    {
        $Code = {
            $ProductName = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name ProductName).ProductName
            Try
            {
                $Version = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name ReleaseID –ErrorAction Stop).ReleaseID
            }
            Catch
            {
                $Version = "N/A"
            }
            $CurrentBuild = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name CurrentBuild).CurrentBuild
            $UBR = (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' –Name UBR).UBR
            $OSVersion = $CurrentBuild + "." + $UBR


           # Get-CimInstance Win32_OperatingSystem to list Build number in the machine
            $getOS = gcim Win32_OperatingSystem 
            # Assign the initial value for this variable
            $currentOSVersion = "Unknown OS"
            # Check Build number is corresponding with Windows 10 and Windows Server OS edition.
            # https://docs.microsoft.com/en-us/windows/release-health/release-information 
            # https://docs.microsoft.com/en-us/windows-server/get-started/windows-server-release-info

             Switch -WildCard ($getOS.BuildNumber){
            # if BuildNumber is 19043, Windows version is Windows 10 21H1 and so on.
            '*19043*'{$currentOSVersion = "21H1"}
            '*19042*'{$currentOSVersion = "20H2"}
            '*19041*'{$currentOSVersion = "2004"}
            '*18363*'{$currentOSVersion = "1909"}
            '*18362*'{$currentOSVersion = "1903"}
            '*17763*'{$currentOSVersion = "1809"}

            # if BuildNumber is 14393, Windows version is Windows Server 2016 version 1067 and so on.
            '*14393*'{$currentOSVersion = "1607"}
            '*17763.107*'{$currentOSVersion = "1809"}
            '*18363.418*'{$currentOSVersion = "1909"}
            '*19041.264*'{$currentOSVersion = "2004"}
            '*19042.508*'{$currentOSVersion = "20H2"}
            '*20348.169*'{$currentOSVersion = "2022"}
            }

            $TempTable = New-Object System.Data.DataTable
            $TempTable.Columns.AddRange(@("ComputerName","Windows Edition","Version","OS Build"))
            [void]$TempTable.Rows.Add($env:COMPUTERNAME,$ProductName,$currentOSVersion,$OSVersion)
        
            Return $TempTable
        }

        If ($Computer -eq $env:COMPUTERNAME)
        {
            $Result = Invoke-Command –ScriptBlock $Code
            [void]$Table.Rows.Add($Result.Computername,$Result.'Windows Edition',$Result.Version,$Result.'OS Build')
        }
        Else
        {
            Try
            {
                $Result = Invoke-Command –ComputerName $Computer –ScriptBlock $Code –ErrorAction Stop
                [void]$Table.Rows.Add($Result.Computername,$Result.'Windows Edition',$Result.Version,$Result.'OS Build')
            }
            Catch
            {
                $_
            }
        }

    }

}
End

{
    Return $Table
}
}

Run the command.

PS C:\shared\ Get-MyWindowsVersion

Query all Windows 10 domain-joined on Active Directory.

(Get-ADComputer -filter {OperatingSystem -Like '*Windows 10*'})

Query all Windows Server 2016 domain-joined on Active Directory.

Get-ADComputer -filter {OperatingSystem -Like '*Windows Server*'}

A script to detect Windows 10 OS’s current patch version if the machine is online.

$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Query Windows 10 domain-joined on Active Directory
$computername = (Get-ADComputer -filter {OperatingSystem -Like '*Windows 10*'}).name
foreach($computer in $computername){
    $ping_result = Test-Connection -ComputerName $computer -Count 1 -Quiet
        if($ping_result){
        get-windowsversion -computer $computer
#        | Select-Object -Property ComputerName,  'Windows Edition', Version, 'OS build' |
#        Sort-Object 'OS build' | export-csv -NoTypeInformation -Append "$filename.csv"
        }
        else{
            Write-Host "Host ICMP: failure"
        }
    }
Save the output to csv file

# Get date when running the script
$filename = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
# Query Windows 10 domain-joined on Active Directory
$computername = (Get-ADComputer -filter {OperatingSystem -Like '*Windows 10*'}).name
foreach($computer in $computername){
        # the machine is offline if the script is not ablt to get any echo reply from sending 3 echo requests
        $ping_result = Test-Connection -ComputerName $computer -Count 3 -Quiet
        # if the machine is online
        if($ping_result){
        # get Windows 10 current patch information and append the result yo csv file
            get-windowsversion -computer $computer | 
            Select-Object -Property ComputerName,  'Windows Edition', Version, 'OS build' |
            Sort-Object 'OS build' | export-csv -NoTypeInformation -Append "$filename.csv"
        }
#        else{
#            Write-Host "Host ICMP: failure"
#        }
}

Configure host-check for SSLVPN connections on FortiGate

This is a diagram to do a host-check SSLVPN connections lab.

Enable tunnel-mode SSLVPN

Enable host-check for Antivirus and Firewall enabled on Fortinet.

Windows machine is up to date and Windows Firewall is enabled.

Setup Forticlient on Windows machine.

Move to unpatched and disabled Windows firewall’s machine.

SSLVPN connection is failed.

Enabled Windows Firewall

Windows OS is not up to date.

Creating an SSLVPN connection again, it was failed.

Checking on Forticlient log and Fortinet Web management console.

Configure DoS Policy on FortiGate

This is a diagram to do a Fortinet Dos Lab.

Fortinet – Policy and Objects – IPv4 DoS Policy.

Change TCP_port_scan setting to 5 and ICMP_flood setting to 4.

Configure quarantine setting on the Fortinet DoS Policy.

config firewall DoS-policy

    edit 1

        set interface “port1”

        set srcaddr “all”

        set dstaddr “all”

        set service “ALL”

        config anomaly

            edit “icmp_flood”

                set status enable

                set log enable

                set quarantine attacker

                set quarantine-expiry 5m 

                set quarantine-log disable

                set threshold 4

            next

        config anomaly

            edit “tcp_port_scan”

                set status enable

                set log enable

                set quarantine attacker

                set quarantine-expiry 5m 

                set quarantine-log disable

                set threshold 5

            next

Sending 5 packets per second, Fortinet starts to block the excessive ICMP packets.

Check Fortinet Anomaly log.

Fortinet Fortiview.

Fortinet Monitor – Banned IP. AT IP Address was blocked by Fortinet Firewall.

Doing port scan on Kali machine by using Nmap command.

Fortinet was blocked port scan on the opened port 80.

Install Cisco CME on LinuxMint

Below is a topology that is used for this lab.

On LinuxMint

+ Install Dynamips, Dynagen

sudo apt install dynagen dynamips bridge-utils uml-utilities

+ Backup network interface config file
sudo cp /etc/network/interfaces ~

Edit network config file to create a bridged network interface (br0) for physical interface (enp0s3).
sudo nano /etc/network/interfaces

auto lo enp0s3 br0
iface lo inet loopback

iface br0 inet static
bridge_ports enp0s3
address 192.168.5.20
netmask 255.255.255.0
gateway 192.168.5.1

Restart networking service. It failed. We need to restart Linuxmint to make it work after restarting the service.
sudo service networking restart

Check IP address configuration and ping google.ca.

+ Create a new dynagen for 2 CME Routers.
cd /home/tung
mkdir CME
cd CME

Drag cme.tar and c7200-adventerprisek9-mz.151-4.M.bin file to CME directory.

+ Create a dynagen CME config file.

sudo nano dynagen_cme.conf

f0/0 = nio_tap:tap1
x = 22.0
y = -351.0

autostart = False
[127.0.0.1:2000]
workingdir = /home/tung/CME
udp = 10100
[[7200]]
image = c7200-adventerprisek9-mz.151-4.M.bin
disk0 = 512
#idlepc = 0x6060b654
[[ROUTER r1]]
model = 7200
console = 2221
aux = 2119
#wic0/0 = WIC-1T
#wic0/1 = WIC-1T
#wic0/2 = WIC-1T

[[ROUTER r2]]
model = 7200
console = 2222
aux = 2119
#wic0/0 = WIC-1T
#wic0/1 = WIC-1T
#wic0/2 = WIC-1T

f0/0 = nio_tap:tap2
x = 22.0
y = -351.0

+ Run dynamips program and start both CME Routers
sudo dynamips -H 2000&

list
start /all

Check port 2000, 2221, 2222 are running on LinuxMint.

Open a new tab to console R1.
telnet localhost 2221

Open a new tab to console R2.
telnet localhost 2222

+ Install TFTP service on LinuxMint
Open new terminal
sudo apt install tftpd

sudo nano /etc/xinetd.d/tftp

service tftp
{
protocol =udp
socket_type =dgram
wait =yes
user =nobody
server =/usr/sbin/in.tftpd
server_args =/tftpboot
disable =no
}

sudo mkdir /tftpboot to contain CME image file
sudo cp cme.tar /tftpboot to copy the CME image to /tftpboot folder
Change permission on tftp folder
sudo chmod 777 -R /tftpboot/
Restart xinetd service
sudo systemctl restart xinetd
Check TFTP service is running
netstat -anup | grep 69

+ Configure CME Router
On R1:
enable
conf t
hostname R1
int fa0/0
ip address 192.168.5.7 255.255.255.0
no shut
end

On R2:
enable
conf t
hostname R2
int fa0/0
ip address 192.168.5.8 255.255.255.0
no shut
end

+ Now we need to configure LinuxMint network interface to communicate with both CME Routers
Open new tab
sudo brctl addif br0 tap1 tap2
sudo ifconfig tap1 up
sudo ifconfig tap2 up

Enter ip a command to see all interfaces are up. Test to ping from LinuxMint to R1 and R2.

+ Back to R1 and R2 to load CME image. This process will take time around 1 hour to finish flashing the Router CME image.

On R1:
R1#archive tar /xtract tftp://192.168.5.20/cme.tar disk0:

On R2:
R2#archive tar /xtract tftp://192.168.5.20/cme.tar disk0:

+ Enable telephone service on CME Routers.

On R1:
!!! enable CME GUI on CME Router
ip http server
ip http path disk0:/gui
ip http authentication local
!!! create user and password to manage CME
telephony-service
web admin system name admin password cisco
dn-webedit
time-webedit

sets max amount of phones

max-ephones 5
ip source-address 192.168.5.7 port 2000
!sets max amount of numbers
max-dn 25
system message TUNGLE VOIP
create cnf-files

On R2:
!!! enable CME GUI on CME Router
ip http server
ip http path disk0:/gui
ip http authentication local
!!! create user and password to manage CME
telephony-service
web admin system name admin password cisco
dn-webedit
time-webedit

sets max amount of phones

max-ephones 5
ip source-address 192.168.5.8 port 2000
!sets max amount of numbers
max-dn 25
system message TUNGLE VOIP
create cnf-files

Back to LinuxMinit, open Firefox to access both CMEs via web interface.
http://192.168.5.7/ccme.html
http://192.168.5.8/ccme.html

+ Open Windows VM1 and VM2, then install the Cisco IP communicator on VM1 and VM2.
+ Next, configure Cisco IP Communicator on VM1 point to CME on R1 and VM2 point to CME on R2. Wait for a few minutes, we can see IP phone has successfully registered on CME R1 and R2.

Using Firefox on LinuxMint to configure IP phones. Adding phone and extension number 7822 for R1, and 7922 for R2.

Assign ephone with button 2 for R1 and R2, then restart two Cisco IP phones via command restart on CME R1 and R2
ephone 1
button 2:1

Now configure dial-peer between two CMEs to allow both Cisco IP communicators to communicate together.

R1:
R1(config)#dial-peer voice 2 voip
R1(config-dial-peer)#destination-pattern 79..
R1(config-dial-peer)#session target ipv4:192.168.5.8

R2:
R2(config)#dial-peer voice 1 voip
R2(config-dial-peer)#destination-pattern 78..
R2(config-dial-peer)#session target ipv4:192.168.5.7

Back to Windows VM and test to call from DN 7822 to DN 7922. It works.

Create a Ceph cluster on Proxmox cluster

Ceph is an open-source distributed software solution. It is designed to serve block, file, and object workloads for a cluster system. There are a lot of advantages when using Ceph. Ceph supports distributed object storage on multiple cluster nodes, provides redundancy between cluster nodes and is able to scale out cluster storage nodes with Ceph.

Ceph is able to run on commodity hardware without vendor lock-in. Moreover, Ceph is also a unified storage infrastructure that supports storage clusters that may grow or shrink and allows to add and remove hardware while the Ceph cluster is online.

This lab below is used to deploy three Proxmox nodes on the Ceph clsuter.

Add a new second hard drive on Proxmox1, Proxmox2, and Proxmox3 nodes.

Install Ceph cluster on node 1.

Create an OSD on Proxmox node 1, node 2 and node 3.

Create Ceph Pool on Ceph storage.

Create a new Linux VM on Ceph.

Add this machine to the HA Ceph.

Hard turn off the Proxmox node1.

Linux VM has been migrated to Proxmox node2 with a couple of minutes of downtime.

Doing live migration the VM2 on Proxmox node 2 to node 3.

It is interesting to see there is no downtime when doing live migration VM2 on Proxmox node 2 to node 3 in the Ceph cluster.