Tag Archives: Linux

Count the number of failed root login in Linux server by IP address via PowerShell

Using (e)grep, cut, awk, sed to extract specific information in Linux logs is one of the daily tasks of Linux system administrator.

grep "Failed" '/var/log/auth.log' | grep -v root | awk -F 'from ' '{ print $2} ' | awk '{print $1}' | sort | uniq -c | sort -nr | while read COUNT IP

However, in this article, I want to demonstrate how to use PowerShell to extract the number of failed root login in Linux server.

Download the /var/log/auth.log example file via github (https://github.com/elastic/examples/blob/master/Machine%20Learning/Security%20Analytics%20Recipes/suspicious_login_activity/data/auth.log)

Save it under Downloads directory. Querying the content of the file via Get-content command.

$inputpath = get-content "/Users/tungle/Downloads/auth.log"

Now, I want to explain how to use PowerShell to extract specific information in the log file. If the number of failed attempts is greater than the LIMIT, then it will display count number, IP address, and Geolocation of the IP address.

Firstly, we need to know a format of the IP address via PowerShell regex.

$regex = "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"

Filtering all lines are matched the regex format of the IP address in auth.log file.

$output = $inputpath | Select-String -Pattern $regex -AllMatches

Selecting all lines are matched “failed password for root”.

$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" 

Following the MS link, I use matches method to populate the returned MatchCollection object (https://learn.microsoft.com/en-us/dotnet/api/system.text.regularexpressions.regex.matches?view=netframework-4.7.2). % is an alias of foreach-object.

$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches }

Next, getting IP addresses of the failed login in the log file.

$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches } | % { $_.Value }

Group the IP address property together.

$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches } | % { $_.Value } `
| Group-Object

Check if the number of failed attempts is greater than the LIMIT (>10 failed login attempts).

$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches } | % { $_.Value } `
                    | Group-Object |  Select-Object Name, Count | Where-Object { $_.Count -gt 10 }

Using the PS script block below to detect attempted IP address, count, and country. Basically, the script will check all lines in the $output variable above and output the top IP address and county attempts.

ForEach($line in $output){
    $IP = $line.Name
    #$IP
    # Query Geolocaltion of the IP addresses via free API
    $result = Invoke-RestMethod -Method Get -Uri http://ip-api.com/json/$IP
    # Create a PSCustomObject to save Count, IP address and Country attempts 
    $myObject = [PSCustomObject]@{
                Count = $line.Count
                "IP Address" = $line.Name
                #IP = $result.query
                Country = $result.Country
}
$myObject
}

Below is a PS script block to check the failed root attempts.

$inputpath = get-content "/Users/tungle/Downloads/auth.log"
#$regex = ‘\b\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\b’
$regex = "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"
#$inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root"
#$inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches }
$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches } | % { $_.Value } `
                    | Group-Object |  Select-Object Name, Count | Where-Object { $_.Count -gt 10 }
ForEach($line in $output){
    $IP = $line.Name
    #$IP
    $result = Invoke-RestMethod -Method Get -Uri http://ip-api.com/json/$IP
    # Create a PSCustomObject to save Count, IP address and Country attempts 
    $myObject = [PSCustomObject]@{
                Count = $line.Count
                "IP Address" = $line.Name
                #IP = $result.query
                Country = $result.Country
}
$myObject
}

This is a PS script (show-attacker.PS1) to run in a cloud-based Linux virtual machine.

$inputpath = get-content "/var/log/auth.log"
#$inputpath = get-content "/Users/tungle/Downloads/auth.log.txt"
$regex = "\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b"
$output = $inputpath | Select-String -Pattern $regex -AllMatches | Select-String "failed password for root" | % { $_.Matches } | % { $_.Value } `
| Group-Object |  Select-Object Name, Count | Where-Object {$_.Count -gt 20}
ForEach($line in $output){
        $IP = $line.Name
        $result = Invoke-RestMethod -Method Get -Uri http://ip-api.com/json/$IP
        # Sleep a second 
        Start-Sleep 1
    	#Write-Output $_count
        $myObject = [PSCustomObject]@{
        	Count = $line.Count
		"IPAddress" = $line.Name
            	#IP = $result.query
            	Country = $result.Country
}
    $myObject
}

Run the script in Linux server.

./show-attacker.PS1 | Sort-Object Count -Descending

Finally, we can extract specific information of authentication logs in Linux server by using PowerShell.

Deploying WordPress and MySQL with Kubernetes on AWS

This is a diagram that I have used for this lab.

+ Create a Ubuntu Linux instance with 2GB RAM and 30GB storage for Kubernetes.

+ Create a MySQL deployment file.

#mysql-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress-mysql
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mysql-pv-claim

+ Create a WordPress deployment file

#wordpress-deployment.yaml

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: frontend
  type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wp-pv-claim
  labels:
    app: wordpress
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app: wordpress
      tier: frontend
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: frontend
    spec:
      containers:
      - image: wordpress:4.8-apache
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-pass
              key: password
        ports:
        - containerPort: 80
          name: wordpress
        volumeMounts:
        - name: wordpress-persistent-storage
          mountPath: /var/www/html
      volumes:
      - name: wordpress-persistent-storage
        persistentVolumeClaim:
          claimName: wp-pv-claim

+ Download the MySQL deployment configuration file.

sudo curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml

+ Download the WordPress configuration file.

sudo curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml

+ Create a kustomization.yaml.

secretGenerator:
- name: mysql-pass
  literals:
  - password=YOUR_PASSWORD
resources:
  - mysql-deployment.yaml
  - wordpress-deployment.yaml

+ Enable DNS dashboard storage.

microk8s enable dns dashboard storage

+ Apply and verify

microk8s kubectl apply -k ./

+ Verify a PersistentVolumeClaims (PVC) got dynamically provisioned.

microk8s kubectl get pvc

+ Verify the Pod is running.

microk8s kubectl get pods

+ Check Kubernetes is running.

microk8s kubectl get all --all-namespaces

+ Expose port 80 via External IP address (10.0.0.10) of Kubernetes instance on AWS. This allows accessing WordPress via the Internet.

microk8s kubectl patch svc wordpress -n default -p '{"spec": {"type": "LoadBalancer", "externalIPs":["10.0.0.10"]}}'

Check the port 80 is listening on the Kubernetes host.

+ Verify the WordPress service is running.

Access the WordPress on Kubernetes. (http://54.165.173.81)

Sending FortiGate logs to Graylog open-source log management on AWS via IPSEC VPN site-to-site

This is a diagram that I have used to build this lab.

There are a couple of steps in this lab.

  • Configure IPSEC VPN site-to-site IKEv2 between FortiGate and AWS.
  • Implementing Graylog open-source log management on a Linux instance on AWS.
  • Download FortiGate Content Pack (.json file) for Graylog.
  • Upload the file into Graylog.
  • Configure FortiGate to send logs to Graylog via Graylog’s IP address and the destination UDP port 1500.

Use the link below to know how to deploy the VPN site-to-site between FortiGate on-prem and AWS.

https://tungle.ca/?p=2753

Create a new Linux instance (4GB RAM) to install Graylog.

On Security Group, create a couple of following rules to allow FortiGate LAN subnets to communicate with Graylog on AWS LAN subnets.

SSH to the Linux instance.

+ Update your system and install needed packages.

sudo hostnamectl set-hostname graylog
sudo yum update -y
sudo yum install epel-release
sudo wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/p/pwgen-2.08-1.el7.x86_64.rpm
sudo rpm -ivh pwgen-2.08-1.el7.x86_64.rpm

+ Install JAVA

sudo yum install java-1.8.0-openjdk-headless.x86_64 -y
sudo java -version

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

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

+ Install MongoDB.

sudo yum install mongodb-org -y

+ Enable and start the mongoDB service on the 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

+ Installing Elasticsearch.

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

sudo nano /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

Install the open-source version of Elasticsearch.

sudo yum install elasticsearch-oss -y
#Edit the elasticsearch.yml file on /etc/elasticsearch/elasticsearch.yml
sudo nano /etc/elasticsearch/elasticsearch.yml

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

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'

+ Installing the Graylog.

Now install the Graylog repository configuration with the following command.

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

Install Graylog-server.

sudo yum install graylog-server -y

Configure Graylog.

Generate password_secret.

pwgen -N 1 -s 96

[ec2-user@ip-10-0-0-64 ~]$ pwgen -N 1 -s 96
Bv6a46BXTALlfI3VRZ3ACfzBoIZOo3evqd7v7FY0fsrSXNZDflPcWRtYoxRrm5BZfMvq2TKffWEobYL6iSwBW908gpSC9z79

Generate root_password_sha2.

echo -n graylog@123 | sha256sum | cut -d” ” -f1

[ec2-user@ip-10-0-0-64 ~]$ echo -n graylog@123 | sha256sum | cut -d” ” -f1
cc41de147e5c624c6a7c230648545f6d14f82fa0e591148dc96993b3e539abfc

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

sudo nano /etc/graylog/server/server.conf
Comment the following line.
#http_bind_address = 127.0.0.1:9000

Add the following line with IP address of Graylog.
http_bind_address = 10.0.0.64:9000 

Enable and start Graylog service.

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

Check Graylog Server listening port.

netstat -antp | grep 9000

Access Graylog web interface from Kali’s machine on FortiGate LAN subnets.

http://10.0.0.4:9000
user:admin
password:graylog@123

Back to FortiGate, configure the Syslog setting to send logs via the Graylog server on its IP address 10.0.0.64 with a destination port is 1500.

config log syslogd setting
set status enable
set server 10.0.0.64
set port 1500
end 
show log syslogd setting

On Graylog.

Download FortiGate Content Pack from Github.

https://marketplace.graylog.org/addons/f1b25e9c-c908-41e4-b5de-4549c500a9d0

https://github.com/teon85/fortigate6.4_graylog4

Download the JSON file (fortigate6.4_graylog4.json)

Go to System – Content Packs – Upload. Select the file (fortigate6.4_graylog4.json) and upload.

Click Install.

Change the Syslog port to 1500.

FortiGate dashboard.

Install Docker Swarm Cluster on Debian 10

This is diagram is used to deploy the 3 nodes Docker swarm.

On three nodes: docker01, docker02, and docker03.

apt-get update

Install Docker CE on Debian 10.

apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

Add Docker GPG key and Docker repository.

curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"

Install Docker Engine

apt-get update
apt-get install docker-ce docker-ce-cli

Enable and start Docker daemon.

systemctl start docker
systemctl enable docker

+ Initialize Docker Swarm Cluster on node 1: docker01

docker swarm init --advertise-addr 192.168.5.46

Join docker02 and docker03 to the cluster.

Create a custom httpd image with the listening port is 8847.

We can check if the worker nodes have joined to cluster successfully using the command below:

docker node ls

+ Deploy Applications on Docker Swarm

Below is an example to deploy an Apache web service with the listening port is 8847 and service name is tunghttp

docker service create --name tunghttp -p 8847:80 httpd

+ Scale Applications on Docker Swarm to have high availability and high performance on 3 nodes.

docker service scale tunghttp=3
docker service ps tunghttp

Create a new index.html file on the docker host. Then, copy the file to the Apache webserver directory as a screenshot below.

<html>
<head>
<title>Tung A01</title> 
</head>
<body>
	<h1 Welcome to the web server that is deployed by Docker </h1>
	<img src="http://imagefromtheinternet.jpg">
</body>
</html>

Open the web browser and access the web server via port 8847 on three Docker IP addresses.

Check three nodes.

 docker node ls

Check the 8847 port is running on the Docker node.

netstat -ant | grep 8847

 Build Kubernetes cluster with MicroK8s

Below is a process to install the Kubernetes cluster on three nodes. with MicroK8s.

+ Deploying MicroK8s on node 1, node 2, and node 3

Install MicroK8s directly from the snap store.

sudo apt install snapd

To follow a specific upstream release series it’s possible to select a channel during installation, for example, v1.18 series.

sudo snap install microk8s --classic --channel=1.18/stable

Configure your firewall to allow pod-to-pod and pod-to-internet communication.

sudo ufw allow in on cni0 && sudo ufw allow out on cni0
sudo ufw default allow routed

Dashboard, core-dns, or local storage can be enabled by running the microk8s enable command:

microk8s enable dns dashboard storage
sudo usermod -a -G microk8s tung
sudo chown -f -R tung ~/.kube
newgrp microk8s

Get the output of the first node.

Get token.

Copy and paste the token on the following screenshot.

Kubernetes dashboard.

Get status of mircok8s service.

Do previous steps on node 2 and node 3. We do not need to install dashboard service on node 2 and node 3.

+ Create a MicroK8s multi-node cluster.

Now let’s focus on creating the Kubernetes cluster. On the first node run a command below.

microk8s add-node

This command will give you the following output:

On node 2, join the cluster.

Repeat this process (including generating a token, run it from the joining node) for the third node.

+ Deploy a sample containerized application

Let’s now create a microbot deployment with three pods via the kubectl cli. Run this on any of the control plane nodes:

microk8s kubectl create deployment microbot --image=dontrebootme/microbot:v1
microk8s kubectl scale deployment microbot --replicas=3

To expose our deployment we need to create a service:

microk8s kubectl expose deployment microbot --type=NodePort --port=80 --name=microbot-service

After a few minutes, check your cluster.

Check IP address of the K8S node.

Access micro-bot service via the port 30711.

Kubernetes dashboard.

Install Kubernetes on LinuxMint

Firstly, install Kubernetes and snapd package.

sudo apt install kubernetes snapd

Get an error as a screenshot below.

Enter “sudo rm /etc/apt/preferences.d/nosnap.pref”

sudo apt-get update
sudo apt-get install

Run the command above again.

Next, install Kurbenetes.

kubernetes install

+ Create our first app deployment using nginx.

microk8s.kubectl create deployment nginx --image nginx

+ Add your user to the microk8s admin group.

+ View all running services.

microk8s.kubectl get all

+ Enable Dashboard.

microk8s.enable dns dashboard

+ List all namespaces in microk8s. Take note of the IP address of the Kubernetes dashboard.

microk8s.kubectl get all –all-namespaces

Kubernetes has created a couple of new network interfaces.

+ View token.

token=$(microk8s kubectl -n kube-system get secret | grep default-token | cut -d " " -f1)
microk8s kubectl -n kube-system describe secret $token

+ Access to Kubernetes dashboard https://10.152.183.198, and enter the token on the previous step.

Implementing OpenVPN server on Debian 10

Below is a lab topology to use to implement the OpenVPN solution on Debian 10.

In this lab, we need to make sure clients on the Internet are able to create secure OpenVPN connections to the OpenVPN server. Also, the OpenVPN client is able to access inside the network beside the VPN tunnel (LAMP subnet: 192.168.131.0/24), and still access the Internet. Moreover, the Split tunneling feature should be used to make sure only traffic is related to accessing the LAMP subnet will be routed via the OpenVPN tunnel. All other traffic will use a public network adapter (Internet).

IP addresses of Debian OpenVPN server.

Access SSH from LinuxMint to easy to copy and paste commands.

Upgrade Debian’s machine.

apt-get update -y
apt-get upgrade -y

+ Enable IP Forwarding

Edit the file /etc/sysctl.conf and add the line below at the end of the file.

net.ipv4.ip_forward = 1

+ Enable proxy_arp for arp entry to appear on the OpenVPN server.

echo 1 > /proc/sys/net/ipv4/conf/all/proxy_arp

+ Add a line below into /etc/sysctl.conf to make it permanent.

net.ipv4.conf.all.proxy_arp=1

Run the following command to make the changes work.

sysctl -p

+ Install OpenVPN server.

apt-get install openvpn -y

Copy the easy-rsa directory from /usr/share directory to /etc/openvpn directory.for managing SSL certificates.

cp -r /usr/share/easy-rsa /etc/openvpn/

+ Set up Certificate Authority (CA)

cd /etc/openvpn/easy-rsa
nano vars
#Add information below to the file.
set_var EASYRSA                 "$PWD"
set_var EASYRSA_PKI             "$EASYRSA/pki"
set_var EASYRSA_DN              "cn_only"
set_var EASYRSA_REQ_COUNTRY     "CANADA"
set_var EASYRSA_REQ_PROVINCE    "BC"
set_var EASYRSA_REQ_CITY        "Vancouver"
set_var EASYRSA_REQ_ORG         "BCIT Student"
set_var EASYRSA_REQ_EMAIL	"admin@newhorizon.ca"
set_var EASYRSA_REQ_OU          "BCIT Student"
set_var EASYRSA_KEY_SIZE        2048
set_var EASYRSA_ALGO            rsa
set_var EASYRSA_CA_EXPIRE	7500
set_var EASYRSA_CERT_EXPIRE     365
set_var EASYRSA_NS_SUPPORT	"no"
set_var EASYRSA_NS_COMMENT	"BCIT Student CERTIFICATE AUTHORITY"
set_var EASYRSA_EXT_DIR         "$EASYRSA/x509-types"
set_var EASYRSA_SSL_CONF        "$EASYRSA/openssl-easyrsa.cnf"
set_var EASYRSA_DIGEST          "sha256"

 Run the following command to initiate your own PKI.

./easyrsa init-pki

Build the CA certificates.

./easyrsa build-ca

+ Generate Server Certificate Files.

./easyrsa gen-req tung-server nopass

+ Sign the public key of the Server Using Root CA.

./easyrsa sign-req server tung-server

Verify cert.

openssl verify -CAfile pki/ca.crt pki/issued/tung-server.crt 

+ Create a strong Diffie-Hellman key to use for the key exchange

./easyrsa gen-dh

After creating all certificate files, copy them to the /etc/openvpn/server/ directory.

cp pki/ca.crt /etc/openvpn/server/
cp pki/dh.pem /etc/openvpn/server/
cp pki/private/tung-server.key /etc/openvpn/server/
cp pki/issued/tung-server.crt /etc/openvpn/server/

+ Generate Client Certificate and Key File

./easyrsa gen-req client nopass

Next, sign the client key using your CA certificate.

./easyrsa sign-req client client

Next, copy all client certificate and key file to the /etc/openvpn/client/ directory

cp pki/ca.crt /etc/openvpn/client/
cp pki/issued/client.crt /etc/openvpn/client/
cp pki/private/client.key /etc/openvpn/client/

+ Configure OpenVPN Server

nano /etc/openvpn/server.conf
#---
root@debian10new:~# cat /etc/openvpn/server.conf 
port 1194
proto udp
# USE TCP
#port 4443
#proto tcp-server
dev tun
ca /etc/openvpn/server/ca.crt
cert /etc/openvpn/server/tung-server.crt
key /etc/openvpn/server/tung-server.key
dh /etc/openvpn/server/dh.pem
# OpenVPN tunnel IP address range
server 172.16.1.0 255.255.255.0
# server 192.168.131.0 255.255.255.0
# route all traffic via OpenVPN
push "redirect-gateway def1"
push "dhcp-option DNS 8.8.8.8"
duplicate-cn
cipher AES-256-CBC
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
auth SHA512
auth-nocache
keepalive 20 60
persist-key
persist-tun
#disable compress lz4 because of error on OpenVPN client
#compress lz4
daemon
user nobody
group nogroup
log-append /var/log/openvpn.log
verb 3
root@debian10new:~# 
#---

+ Start OpenVPN service.

systemctl start openvpn@server
systemctl enable openvpn@server
systemctl status openvpn@server

Show OpenVPN tunnel.

ip a show tun0

+ Generate client configuration.

nano /etc/openvpn/client/client.ovpn
#---
client
dev tun
# USE UDP
proto udp
remote 10.0.0.52 1194

# USE TCP
#proto tcp-server
# Public IP address on OpenVPN is 10.0.0.52
#remote 10.0.0.52 4443
ca ca.crt
cert client.crt
key client.key
#remote-cert-tls server
cipher AES-256-CBC
# Below lines is important to allow OpenVPN is still accessing the Internet when making OpenVPN session.
# Split tunneling on OpenVPN
# https://forums.openvpn.net/viewtopic.php?t=8229
route-nopull
# the LAN subnet that you need to access via VPN tunnel
route 192.168.131.0 255.255.255.0 vpn_gateway
auth SHA512
auth-nocache
tls-version-min 1.2
tls-cipher TLS-DHE-RSA-WITH-AES-256-GCM-SHA384:TLS-DHE-RSA-WITH-AES-256-CBC-SHA256:TLS-DHE-RSA-WITH-AES-128-GCM-SHA256:TLS-DHE-RSA-WITH-AES-128-CBC-SHA256
resolv-retry infinite
#compress lz4
nobind
persist-key
persist-tun
mute-replay-warnings
verb 3
#---

+ Configure routing using UFW.

By default, the UFW firewall is not installed in Debian 10.

apt-get install ufw -y

Configure UFW to accept the forwarded packets.

nano /etc/default/ufw
# Change the following line:

DEFAULT_FORWARD_POLICY="ACCEPT"
nano /etc/ufw/before.rules

Note: Replace ens3 with the name of your public network interface in Debian OpenVPN server is ens35.

Allow the default OpenVPN port 1194 and OpenSSH. Then, reload the UFW firewall.

ufw allow 1194/udp
ufw allow OpenSSH
ufw disable
ufw enable

+ Connect OpenVPN from a client.

Install OpenVPN from the Kali machine.

apt-get install openvpn -y

On the client machine, run the command below to download all the client configuration files.

# public-vpn-server-ip: is 10.0.0.52
scp -r root@public-vpn-server-ip:/etc/openvpn/client .

Check OpenVPN tunnel.

On OpenVPN client.

ping 8.8.8.8 (Internet)

ping 192.168.131.134 (OpenVPN gw tunnel)

ping 192.168.131.128 (LAMP server behind OpenVPN server)

We can see split tunneling is working well on OpenVPN.

Access LAMP server.

On Debian OpenVPN server.

Check routing table on OpenVPN server.

Check OpenVPN logs on the OpenVPN server.

Monitor traffic on the OpenVPN server. OpenVPN traffic is using port 1194 UDP. OpenVPN traffic is encrypted using this tunnel.

Implementing open-source Wazuh SIEM

Wazuh is a free, open-source, and enterprise-ready security monitoring solution for threat detection, integrity monitoring, incident response, and compliance.

Below is a topology to implement Wazuh solution.

Below are a couple of steps in this lab.

  • Install Wazuh on LinuxMint
  • Configure Agentless on LAMP server
  • Install Agent on WordPress

+ Install Wazuh on LinuxMint 20.

Following Wazuh link below to install it into LinuxMint 20

https://documentation.wazuh.com/current/installation-guide/open-distro/distributed-deployment/step-by-step-installation/index.html

Login to Wazuh management interface.

+ Using a link below to Configure Agentless monitoring on Wazuh.

https://documentation.wazuh.com/current/user-manual/capabilities/agentless-monitoring/how-it-works.html

To set up that method of access, firstly you need to create ssh keys for the user ossec which is the account the agentless scripts run.

sudo -u ossec ssh-keygen

Copy SSH public key to Debian server that you want to monitor via agentless.

Using the add the option will specify a new device to be added to the manager. “NOPASS” may be entered as the password to use public-key authentication rather than using a password.

Back to Wazuh management interface and add the code below into ossec.conf file to monitor Linux servers with any changes on /bin / etc and /sbin directory.

<agentless>
  <type>ssh_integrity_check_linux</type>
  <frequency>3600</frequency>
  <host>root@192.168.5.41</host>
  <state>periodic</state>
  <arguments>/bin /etc/ /sbin</arguments>
</agentless>

Create a new file under /etc/tung and tung1 user. Security events have been generated on Wazuh from Debian server.

/var/ossec/bin/wazuh-control restart

Wazuh Security Dashboard.

+ Install Wazuh agent on Debian server.

Follow the link below to install Wazuh agent.

https://documentation.wazuh.com/current/installation-guide/wazuh-agent/wazuh-agent-package-linux.html

# Add the Wazuh repository
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | apt-key add -
# Add the repository:
echo "deb https://packages.wazuh.com/4.x/apt/ stable main" | tee -a /etc/apt/sources.list.d/wazuh.list
# Update the package information:
apt-get update
# Deploy a Wazuh agent
WAZUH_MANAGER="192.168.5.34" apt-get install wazuh-agent
# Enable and start Wazuh
systemctl daemon-reload
systemctl enable wazuh-agent
systemctl start wazuh-agent

Wazuh agent on Windows machine.

Install Apache Web server with Ansible

Below is the topology that I have used to install the Apache webserver via Ansible.

This image has an empty alt attribute; its file name is image-460.png

Make sure the Debian server allows Linuxmint to access by using Public key authentication.

On Linuxmint sever.

Create a new tungapache.yaml file

---
- hosts: tunglamp
  become: yes
  vars:
    firstname: "XXX"
    lastname: "YYY"
  tasks:
    - name: Update Debian Server 10 System packages
      become: yes
      apt:  update_cache=yes
    - name: install apache2
      apt: name=apache2 state=latest
    - name: Copy index text page
        template:
          src: "files/index.html.j2"
          dest: "/var/www/html/index.html"

Add Debian server with corresponding IP address information on hosts file.

Go to /etc/ansible directory and create a new files directory.

#pwd /etc/ansible
sudo mkdir files
sudo touch index.html.j2 && sudo nano index.html.j2
<html>
<head>
	<title>{{ firstname}} - {{ lastname }}</title> 
</head>
<body>
	<h1>{{ firstname }} - {{ lastname }}</h1> 
	<h3>Welcome to Tung's Ansbile Test Page</h3>
	<img src="http://imagefromtheinternet.jpg">
</body>
</html>

Run ansible-playbook to install apache webserver on remote Debian Linux server.

ansible-playbook -i /etc/ansible/hosts tungapache.yaml -u root

Check web content on the Debian server.

http://192.168.5.27/index.html

Install Ansible on Linux

The lab below simulates how to check a Linux server with Ansible.

Install Ansible on Linuxmint.

sudo apt install ansible

Set a password root for Linuxmint.

sudo passwd root

Install a new Debian Linux Server to test.

Install sshd service on Linuxmint.

sudo apt install ssh

Modify /etc/hosts.

Create a hosts file under /etc/ansible directory.

Create a new group_vars directory under /etc/ansible.

sudo mkdir group_vars
cd /etc/ansible/group_vars

Create a new tunglamp file.

Try to run a command and it fails.

ansible -m ping all -vvv

We need to setup Public key authentication on LinuxMint.

ssh-keygen -b 4096

Copy the key to the Debian server that you want to access.

ssh-copy-id root@192.168.5.27

Run the command below to make sure you can access to Debian server without a password.

ssh root@192.168.5.27

Check Debian server via Ansible.

ansible -m ping tunglamp
ansible -m shell -a 'free -m' tunglamp
ansible -m shell -s 'ifconfig -a | grep inet' tunglamp