Hexadecimal basics using basic Linux utilities

This is short guide on how to convert strings and decimal values to hexadecimal and vice-versa using simple Linux utilities such as xxd and printf.

  1. To convert a string to hexadecimal, you can use xxd in Linux.

For example: To convert a string “kali” to hexadecimal, you can use the below format.

[email protected]:~$ echo -n kali | xxd
00000000: 6b61 6c69 kali

To group and display the output a single character at a time, use -c  flag with argument 1.

[email protected]:~$ echo -n kali | xxd -c1
00000000: 6b k
00000001: 61 a
00000002: 6c l
00000003: 69 i

This means the following:

00000000: 6b k <- k is a single character and its hexadecimal value is 6b
00000001: 61 a <- a is a single character and its hexadecimal value is 61
00000002: 6c l <- l is a single character and its hexadecimal value is 6c
00000003: 69 i <- i is a single character and its hexadecimal value is 69

2. Convert Hexadecimal value back to string:

[email protected]:~$ echo -n "6b61 6c69" | xxd -r -p
kali

Dont worry about the spaces, it should still work.

[email protected]:~$ echo -n "6b616c69" | xxd -r -p
kali[email protected]:~$

3. Convert decimal (number) to hexadecimal

-Lets say you want to convert number 12 to decimal value. To do so, you could use printf as shown below.

[email protected]:~$ printf "%x\n" 12
c

From above output, the hexadecimal value for number 12 (aka decimal 12) is character c.

To find hexadecimal values for values from 1 to 255, you could run through it in a loop

for num in {1..255}; do printf "%x\n" $num ; done | less

Hope these help.

PS: Knowing hexadecimal does come in handy while learning/debugging different protocols.

How to fix “Error opening terminal: xterm-termite” when trying to SSH to a remote host

I am using “termite” on my ArchLinux machine but when I try to SSH to a remote linux machine(Ubuntu) to run some commands, it throws me an error “Error opening terminal: xterm-termite“. This a post on how to fix it.

Quick Fix:

If you are already SSH’ed into the remote machine and you see this issue, you could update the TERM variable on the remote system: (Run on remote system)

export TERM=xterm-256color

Permanent Fix:

The permanent fix is to edit your local ~/.bashrc file to include the following:

if [ "$TERM" = xterm ]; then
TERM=xterm-256color;
fi
export TERM=xterm-256color

In my case, I had to add it to my Arch Linux’s ~/.bashrc file. (i.e not on the remote Ubuntu machine that I am connecting to)

Here is a screenshot from my box: (Right click image and open in new team to view in full screen)

arch linux termite i3-gaps

To verify its fixed, open a new terminal (or source ~/.bashrc again) and SSH into the remote machine. Ideally this should be fixed.

Hope this helps!

Note: If you terminal does not support 256-color, then you may need to change the TERM variable to “xterm-color” instead of “xterm-256color”.

Credits/References:

Github

GDB basics with C

This is a beginner level tutorial on learning basics of debugging using GDB by debugging an executable. This post will cover writing a very simple C code, compiling it and then opening the generated executable in GDB for inspecting the working/debugging. The primary objective here is to get familiar with the basics of using GDB.

Requirements:

  1. Any Linux x64 OS. (Linux Mint 20 used in this tutorial)
  2. C compiler – gcc
  3. gdb – for debugging / reverse engineering.
  4. GDB Dashboard (Optional – Makes GDB easier to read)

[Disclaimer: This is blog post adapted from recurse’s original gdb tutorial.(All Credits/References added in the Credits section)]

Setting up the Environment:

  • Install the following tools to setup the basic environment:

sudo apt install vim gcc gdb git python3 python3-pip -y

GDB Dashboard:

  • To make GDB easier to understand and make it non-alien, use GDB Dashboard which is a really good python plugin  for GDB.  Its epic!
  • Run the following to get the gdbinit dotfile.
wget -P ~ https://git.io/.gdbinit

If you would like to check out the source, you can find it  @ https://github.com/cyrus-and/gdb-dashboard

For syntax highlighting, you would need the pygments module. If you are using Python2.x:

pip install pygments

If you are using Python3.x, then use pip3 to install it:

pip3 install pygments

To run gdb without providing any executable, run “gdb” and you should see the something like below:

[email protected]:gdb$ gdb
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
>>> 

To exit out of gdb, type  “quit” .

-Below is a simple C program that initializes an integer value and then returns 0.

cat minimal.c
int main()
{
int i = 1337;
return 0;
}

-Compile the C code and make an executable, using the following flags:

gcc -g minimal.c -o minimal

-The directory should now have a executable with filename minimal.

[email protected]:gdb$ file minimal
minimal: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c918c072d119be6a9d18991e812a5414ecae67e1, for GNU/Linux 3.2.0, with debug_info, not stripped

Debugging the binary using GDB:

-To examine an executable in GDB, use the following format:

gdb <executable_file>

-Here, I would run the following to open the executable for debugging:

gdb minimal

gdb minimal output

Lets check the functions in this program, to do run “info functions”. You should be able to see that this executable has function main().

>>> info functions
All defined functions:

File minimal.c:
1: int main();

Non-debugging symbols:
0x0000000000001000 _init
0x0000000000001030 [email protected]
0x0000000000001040 _start
0x0000000000001070 deregister_tm_clones
0x00000000000010a0 register_tm_clones
0x00000000000010e0 __do_global_dtors_aux
0x0000000000001120 frame_dummy
0x0000000000001140 __libc_csu_init
0x00000000000011b0 __libc_csu_fini
0x00000000000011b8 _fini
Here is a screenshot:

gdb info functions output screenshot

The output also shows that the line number at which main() function is present in the source minimal.c.

From the info functions output, we can also see that function main() is present at line number 1 in source minimal.c.

Breakpoints:

-Lets say we need to examine what a executable is going at a given point of time or to inspect the value of a variable, then we can set one or more breakpoints and run the code upto that breakpoint. You can then examine the the value of a variable upto that breakpoint or directly examine the memory etc.

Breakpoints example: Setting breakpoints using function name

From the previous section,we know that the executable has function main(). Lets start examining the binary using gdb to see the value of “i” at different stages of the execution. To start with,  set a breakpoint at function main using the syntax break <function_name>:

>>> break main
Breakpoint 1 at 0x1129: file minimal.c, line 2.
>>>

To get the list of breakpoints that were set, you can use “info breakpoints”.

>>> info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001129 in main at minimal.c:2

gdb info breakpoints

The above shows that there is one breakpoint which is set at function main() whose starting address in memory is “0x1129” or “0x0000000000001129“.

Note: You can have create multiple breakpoints and they are numbered.

So we have a breakpoint in place, we can run the binary upto the breakpoint that was set. To run the program, use “run” or “r“.

gdb screenshot

This is what it looks like now. (You could now see the GDB dashboard with an insane amount of matrix looking stuff. :P)

[Note:  Right click the image and click on “View Image” / “Open image in new tab” if the image for better visibility. ]

GDB Dashboard screenshot

For this tutorial, we are more interested in few sections of Dashboard as of now –   “Source” , “Threads”, “Variables” and “Assembly” sections.

-The “Source” section has a blip on the line number which shows where exactly in the code where gdb is looking into. So, here, it shows that its in line 2 of the source. After you ran the program, if you re-run “info breakpoints” you can see that the message “breakpoint already hit 1 time“.

>> info breakpoints
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000555555555129 in main at minimal.c:2
breakpoint already hit 1 time

 

[Note:  Right click the image and click on “View Image” / “Open image in new tab” if the image for better visibility. ]

As of now, the debugger is in line 2 where the variable “i” is not yet yet initiated in the program. So, if you try to print the value of “i”, then it should show a value = 0.

To print value of a variable, use the format “print var” or “p var“.

>> p i
$1 = 0

 

print i output screenshot

To go to the next line of code and execute it, use command “next” or “n“.  [Note: If the next line of code was a function, it would execute the full function). In this example, once we ran “r“, the “Source” section now highlights line number 3.

gdb print i screenshot 2

At this point, if you print variable “i”, it still shows value as “0” as the initialization is not complete.

You can also check the “Assembly” section in the GDB Dashboard which shows the disassembled code. So, the highlighted section in green in the  “Assembly” shows the following:

0x0000555555555131 main+8 movl $0x539,-0x4(%rbp)

This is the disassembled code (in AT&T syntax) for “int i = 1337”. We will come back to reviewing the assembly code later.

Run command “n” again in gdb. Now, checking the “Source” section in GDB dashboard, should that we are now on line 4.

Now. check the value of  variable “i” using print.

>>> p i
$3 = 1337

This shows that the value variable “i” is 1337.

(gdb) print i
$2 = 1337

Here is the screenshot for reference.

GDB print i after initialized

To find the type of the variable and the starting memory address of that variable in memory:
>>> print &i
$4 = (int *) 0x7fffffffdb8c

GDB print directly using variable address output

-The above shows that “i” is of “int” type. Additionally, “i” is stored at memory location starting at address 0x7fffffffdb8c

-To check maximum size of int type in memory using the sizeof() function.

>>> p sizeof(int)
$5 = 4

The above output shows that int would occupy 4 bytes of space in memory.

To examine memory using gdb use “x“.

-From above outputs, we know that variable “i” is stored in memory with starting address as 0x7fffffffdb8c. We also do know that i is of type integer and integer type would occupy a maximum of 4 bytes in memory.

To examine a specific memory address, you could use the following format

(gdb) x/FMT <starting_memory_address> 

Here is information from “help x” section:

(gdb) help x
Examine memory: x/FMT ADDRESS.
ADDRESS is an expression for the memory address to examine.
FMT is a repeat count followed by a format letter and a size letter.
Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),
t(binary), f(float), a(address), i(instruction), c(char), s(string)
and z(hex, zero padded on the left).
Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).
The specified number of objects of the specified size are printed
according to the format. If a negative number is specified, memory is
examined backward from the address.

Defaults for format and size letters are those previously used.
Default count is 1. Default address is following last thing printed
with this command or "print".
(gdb)

Here, is an example, to examine data from memory location 0x7fffffffdb8c upto the next bytes (or 4 bytes above 0x7fffffffdb8c) ,  use the following:

>>> x/4xb 0x7fffffffdb8c
0x7fffffffdb8c: 0x39 0x05 0x00 0x00

Alternatively, you can access provide the memory location directly by passing “&i” i.e.  “x/4xb &i”

GDB examine memory location screenshot

The above output shows raw byte by byte representation in memory. Here, 0x39 is one byte in memory and 0x05 is another byte etc.
We also know that int would occupy 4 bytes in memory. Here, this integer takes only 2 bytes out of 4 bytes in memory.

Important: This raw memory representation “0x39 0x05 0x00 0x00” is in “little-endian” format(the least significant bytes of a number come first in memory).
So, you would need to read the hex bytes  “0x39 0x05 0x00 0x00” in reverse order. Hence, the value reversed 0x00 0x00 0x05 0x39 is 00000539.
To get the actual value, we need to convert the hex value to decimal.

You could use trusty bash  to covert hex to decimal by using format “echo $(( 16#$hexNum ))“. Here is what it does look like:

[email protected]:~$ echo $(( 16#00000539 ))
1337

So, “1337” is the decimal value stored in memory location 4 bytes starting from 0x7fffffffdb8c.

So, we now know the value of integer variable starting at memory location 0x7fffffffdb8c is 1337. (i.e. the decimal value of i stored in memory is 1337).

An alternative is to use a online hex to decimal converter such as https://www.binaryhexconverter.com/hex-to-decimal-converter to covert 00000539 to decimal.

-You can also print the raw data using the variable itself by using the following format:

(gdb) x/4xb &i

0x7fffffffdb5c: 0x39 0x05 0x00 0x00

Other formats in GDB:

-To print in decimal format, use x/1dw:

(gdb) x/1dw &i
0x7fffffffdb7c: 1337

-Alternatively, give the memory location as well.

(gdb) x/1dw 0x7fffffffdb7c
0x7fffffffdb7c: 1337

Misc Information:

To check the number of threads, run “info threads“.

>>> info threads
Id Target Id Frame 
* 1 process 6570 "minimal" main () at minimal.c:4
>>> 

This shows there is 1 thread with PID 6570.

Other Interesting Stuff:

Here is a screenshot of the dissembled code of “minimal” binary.

#gdb-assembly.png

The one that we are interested in for now is the instruction highlighted below:

0x0000555555555129 main+0 endbr64
0x000055555555512d main+4 push %rbp
0x000055555555512e main+5 mov %rsp,%rbp
0x0000555555555131 main+8 movl $0x539,-0x4(%rbp)
0x0000555555555138 main+15 mov $0x0,%eax
0x000055555555513d main+20 pop %rbp
0x000055555555513e main+21 retq

The instruction “movl $0x539,-0x4(%rbp)” means => move the value “0x539” to the memory location of register rbp -4.

Differences between AT&T and Intel Syntax:

By default, GDB defaults to displaying in AT&T syntax. Here is what main function dissembled looks like in AT&T syntax:

[email protected]:gdb$ gdb minimal
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from minimal...
>>> disass /m main
Dump of assembler code for function main:
2 {
0x0000000000001129 <+0>: endbr64
0x000000000000112d <+4>: push %rbp
0x000000000000112e <+5>: mov %rsp,%rbp

3 int i = 1337;
0x0000000000001131 <+8>: movl $0x539,-0x4(%rbp)

4 return 0;
0x0000000000001138 <+15>: mov $0x0,%eax

5 }
0x000000000000113d <+20>: pop %rbp
0x000000000000113e <+21>: retq

End of assembler dump.
>>>

-If you don’t like this syntax, you can make GDB use Intel syntax using “set disassembly-flavor intel“.

Here, is an example of main function dissasembled in Intel syntax:

[email protected]:gdb$ gdb minimal
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from minimal...
>>> set disassembly-flavor intel
>>> disass /m main
Dump of assembler code for function main:
2 {
0x0000000000001129 <+0>: endbr64
0x000000000000112d <+4>: push rbp
0x000000000000112e <+5>: mov rbp,rsp

3 int i = 1337;
0x0000000000001131 <+8>: mov DWORD PTR [rbp-0x4],0x539

4 return 0;
0x0000000000001138 <+15>: mov eax,0x0

5 }
0x000000000000113d <+20>: pop rbp
0x000000000000113e <+21>: ret

End of assembler dump.
>>>

Here, you should see subtle differences  such as the AT&T syntax displays “movl $0x539,-0x4(%rbp)” while the same in Intel syntax is “mov DWORD PTR [rbp-0x4],0x539“.

Thats it for now. I will add more tutorials on GDB in the near future.

Happy Debugging!

Sources/References/Credits:

Below are all the credits/references/sources that made writing this blog post possible.

https://www.recurse.com/blog/5-learning-c-with-gdb <- Credits to recurse. I used this as my primary resource to learn GDB and then post my understanding of GDB and C here. Do check them out.
https://github.com/cyrus-and/gdb-dashboard <- Creator of the Epic GDB dashboard
https://www.tutorialspoint.com/gnu_debugger/ <- Great place to start.
https://sourceware.org/gdb/current/onlinedocs/gdb/Set-Breaks.html#Set-Breaks
https://stackoverflow.com/questions/209534/how-to-highlight-and-color-gdb-output-during-interactive-debugging
https://bob.cs.sonoma.edu/IntroCompOrg-RPi/sec-gdb1.html
https://www.binaryhexconverter.com <- Simple online convertor
https://stackoverflow.com/questions/13280131/hexadecimal-to-decimal-in-shell-script
https://www.ibm.com/developerworks/library/l-ia/index.html
Credits to my m8 @bytesareana for decoding the stuff with the memory location.

Filter top using process name in Linux

To display statistics only for a process name that match a string using top, you could use the following:

top -c -p $(pgrep -d',' -f firefox)

Here is a screenshot which only shows stats for firefox:

top filtered output screenshot in Linux

Hope this helps! Cheers!

 

Source/Credits/Reference: StackOverflow

Mount TrueNAS Core Samba share on Linux

This is a guide that describes on how to mount a remote Samba share configured on TrueNAS on to a Linux machine.

 

Login in your Linux machine. (I am using a Linux Mint 19.3 in this demo. This should technically work on other Debian/Ubuntu based systems as well).

Use the following commands to get your current user’s user ID (UID) and group ID (GID) respectively.

id -u $USER
id -G $USER

Create a file /etc/.truenas_creds. This is where you would store the samba credentials.

Replace text in red with the username and password of the remote SMB share which was configured in TrueNas.

cat /etc/.truenas_creds
username=enter_username_here
password=enter_password_here

Modify the file permissions so that root is the owner and set the file permission to 600.

sudo chown root: /etc/.truenas_creds
sudo chmod 600 /etc/.truenas_creds

In your linux machine, create a folder to where you want the contents of the remote samba share to be mounts. For example: create a directory named /mnt/truenas/.

sudo mkdir /mnt/truenas/

-Below is a sample syntax that can be used for populating /etc/fstab.

//ip-of-nas-server/enter-remote-samba-share/location /enter-local-mount/location/here/ cifs credentials=/etc/.truenas_creds,iocharset=utf8,uid=enter_your_uid_here,gid=enter_your_gid_here,noperm 0 0

-Here is what that I added in /etc/fstab.

//192.168.1.12/mnt/truenas /mnt/truenas/ cifs credentials=/etc/.truenas_creds,iocharset=utf8,uid=1000,gid=1000,noperm 0 0

My TrueNAS server’s IP => 192.168.1.12

Remote samba share => /mnt/truenas

Local mount location => /mnt/truenas/

Credentials for samba share => /etc/.truenas_creds

-Once complete, run the following to mount all entries looking at /etc/fstab.

mount -a

-If there are no errors in the above command, check your local mount path to verify that the mount was successful.

ls -l /mnt/truenas/

References:

linuxize

Askubuntu

Bash script to loop through values in a file with space as a separator

Lets say we have a file with list of IPs that are space separated and you want to read each of the values to pass to a loop to perform an operation. Here is an example file with IP Addresses separated  by a space:

cat ips.txt
192.168.1.1 192.168.1.10

Now, lets say you want to loop through these IPs and run a ping command against each of them.

cat ping.sh
#!/bin/bash

# IFS is an internal bash variable. Here, we set its value as space.
IFS=$" "
# Read the file "ips.txt" and store the list of values to a variable "ips"
ips="$(cat ips.txt)"

# Run the following loop which will loop through each of the ips and run a ping test
for ip in $ips; do ping -c 1 $ip; done
# Unset the IFS variable so that it wont mess with the reset of the script
unset IFS

-Running this loop, will loop through the list of IP addresses and perform a ping.

./ping.sh
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.660 ms

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.660/0.660/0.660/0.000 ms
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=0.108 ms

--- 192.168.1.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.108/0.108/0.108/0.000 ms

Hope this helps!

Happy scripting folks! 🙂

Source/References: Link

Monitor a Linux host with Telgraf InfluxDB and Chronograf using Docker

This is a guide on how to monitor a Linux device(s) using Telgraf, InfluxDB and Chronograph. To make things easier, we will be running all these components using Docker.

Requirements:

  • Docker should be installed  [Note: Docker version 19.03.08 was used in this tutorial]
  • Internet connectivity to pull the docker images
  • Custom docker network
  • Sufficient Disk space to store data in InfluxDB

1. Create a custom docker network:

-Lets create a custom docker bridge network. Below, I have created a custom docker network with the name “influxdb”.

docker network create influxdb

You can name it whatever you want. You just need to make sure that name is passed in the –net flag in other docker commands.

You can verify that the network is created using the following command:

docker network ls

-Below are the sample outputs:

[email protected]:~$ docker network ls
NETWORK ID NAME DRIVER SCOPE
0d72e4098315 bridge bridge local
e3808d2b4078 host host local
d2c5b3842508 influxdb bridge local
a25ec7e0c8a2 none null local

 

2. Run InfluxDB:

-InfluxDB is database where all the statistics of the host will be stored. To create an instance of InfluxDB, run the following command pass the network name as well as shown below:

docker run -d --name=influxdb --net=influxdb influxdb

3. Run Telegraf:

-Before you run Telegraf, you would need to create Telegraf config file. Run the below commands to generate a sample Telegraf configuration file.

mkdir telegraf
docker run --rm telegraf telegraf config > telegraf/telegraf.conf
ls telegraf/

-Modify the above telegraf.conf as per your requirement. For starters, you can un-comment the outputs.influx block and the urls section. So, the config file would have the following:

[[outputs.influxdb]]
   urls = ["http://influxdb:8086"]

-The above output block tells Telegraf where the Influxdb database is located.  Once this configuration file is passed to telegraph in the next section, then Telegraf will interact with InfluxDB (read and write data) via API.

-Now that we have the configuration file ready, we can run Telegraf and pass the configuration file.

-Below I am passing /sys /proc and /etc as readonly mounts inside the container. Optionally, I have passed the docker socket as well as a bind mount so that I can monitor the resource usage of docker and the running containers too.

docker run -d --restart=always --name telegraf \
--net=influxdb --hostname=telegraf \
-e "HOST_PROC=/rootfs/proc" \
-e "HOST_SYS=/rootfs/sys" \
-e "HOST_ETC=/rootfs/etc" \
-v $(pwd)/telegraf/telegraf.conf:/etc/telegraf/telegraf.conf:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
-v /sys:/rootfs/sys:ro \
-v /proc:/rootfs/proc:ro \
-v /etc:/rootfs/etc:ro \
telegraf

You can add/modify the source as you wish to monitor more data. You just need to make sure that the the necessary mounts/variables are passed as well.

4. Run Chronograf:

-Chronograf is used to visualize the data using a browser. It can talk to InfluxDB and display the data in forms of graphs etc.

-To run Chronograf, you can run the following docker command:

docker run -d --name chronograf -p 8888:8888 --net=influxdb chronograf --influxdb-url=http://influxdb:8086

-Verify all containers are running using “docker ps -a

[email protected]:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                          NAMES
a9da408e41b0        chronograf          "/entrypoint.sh --in_"   39 seconds ago      Up 38 seconds       0.0.0.0:8888->8888/tcp         chronograf
326255e6d234        telegraf            "/entrypoint.sh tele_"   36 minutes ago      Up 36 minutes       8092/udp, 8125/udp, 8094/tcp   telegraf
51c95679a803        influxdb            "/entrypoint.sh infl_"   About an hour ago   Up About an hour    8086/tcp                       influxdb

The above output shows that all the three containers are up and running.

-Now, you can access the Chronograf Dashboard from your browser by visiting the following URL.

http://localhost:8888

Once you are in the Chronograf UI, you can   navigate to “Host Lists” and click on host to view the collected stats.

Below is a screenshot of Chronograf that is displays the host information:

chronograf graphs


Troubleshooting:

To troubleshoot API issues, you could create a sample container in same  “influxdb” network and install curl in it.

For example: You could create an alpine container attached to the influxdb network.

docker run --net=influxdb -it alpine sh

Then install curl using “apk add curl”. Below is the sample outputs:

/ # apk add curl
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/4) Installing ca-certificates (20191127-r1)
(2/4) Installing nghttp2-libs (1.40.0-r0)
(3/4) Installing libcurl (7.67.0-r0)
(4/4) Installing curl (7.67.0-r0)
Executing busybox-1.31.1-r9.trigger
Executing ca-certificates-20191127-r1.trigger
OK: 7 MiB in 18 packages

-Once curl is installed, Then try the following sample InfluxDB API calls pointing to the InfluxDB endpoint from within the Alpine container:

curl -i -XPOST http://influxdb:8086/query --data-urlencode "q=show databases"

-Below are sample outputs:

/ # curl -i -XPOST http://influxdb:8086/query --data-urlencode "q=show databases"
HTTP/1.1 200 OK
Content-Type: application/json
Request-Id: e58a61db-6fa6-11ea-85a3-0242ac120002
X-Influxdb-Build: OSS
X-Influxdb-Version: 1.7.10
X-Request-Id: e58a61db-6fa6-11ea-85a3-0242ac120002
Date: Thu, 26 Mar 2020 21:15:19 GMT
Transfer-Encoding: chunked

{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"],["telegraf"]]}]}]}

-Here is another example on how to to check if you are able to create a database:

curl -i -XPOST http://influxdb:8086/query --data-urlencode "q=CREATE DATABASE telegraf"

To troubleshoot issues related to Telegraf, you review the docker logs.

docker logs -f telegraf

To troubleshoot issues with InfluxDB, you can manually access InfluxDB’s shell/CLI and run commands (just like you would in other database servers such as MySQL.)

Below is an example on how to view the list of databases from InfluxDB shell.

docker exec -it influx sh
# influx
Connected to http://localhost:8086 version 1.7.10
InfluxDB shell version: 1.7.10
> show databases
name: databases
name
----
_internal
telegraf

I hope this helps. Do share, leave a like/comment below! Cheers!

 

Regards,

ΞXΤЯ3МΞ

 

Sources/References:

https://hub.docker.com/_/telegraf/
https://hub.docker.com/_/chronograf/
https://www.jacobtomlinson.co.uk/monitoring/2016/06/23/running-telegraf-inside-a-container/

Update CA certificate store in Fedora to trust a root CA certificate

Lets assume you have a CA certificate “ca.crt” that you want your system or utilities like curl to trust then you can do the following:

Copy the CA certificate to /etc/pki/ca-trust/source/anchors/

sudo cp ca.crt /etc/pki/ca-trust/source/anchors/

Then you can run the following command to update Fedora’s local CA store.

sudo update-ca-trust

Now you system and tools like curl will trust certificates signed by this CA.

Verify that SSL connection is trusted using curl :

Lets say you have a webserver server whose certificate was signed by the above root CA and the signed certificate is already uploaded to the webserver. You can verify that your Fedora client trusts the certificate using curl.

curl -vvv https://test-server-fqdn.com

In the above curl command, I am passing the verbose flag -vvv which is optional. It is handy for troubleshooting purposes SSL issues.

If the connection is trusted, the SSL connection should work and you would see a message such as below from the curl outputs:

* server certificate verification OK

Note: This was tested on Fedora 31.

Source/References:

https://serverfault.com/questions/394815/how-to-update-curl-ca-bundle-on-redhat
https://www.linux.org/docs/man8/update-ca-trust.html

Run bash script from a Perl script

To run a bash script (Example: bash-script.sh) from inside a perl script, you could use the following syntax:

system("sh", "bash-script.sh")

Note: Here, once the bash script completes execution it will continue with the execution of the perl script.

Example:

Perl Script: perl-script.pl
Bash Script: bash-script.sh

Below is a perl script  “perl-script.pl” which calls an external bash script “bash-script.sh”.

#!/usr/bin/perl
use strict;
use warnings;

print "Running parent perl script. \n";
print "Starting to call external bash script\n";

# Sample Argument to be passed to the bash script
my $my_arg = "ARG1";

# With arguments - pass them inside quotes seperated by commas 
system("sh", "bash-script.sh","$my_arg");

print "Back to parent perl script\n";

Below is the sample “bash-script.sh” which prints the variable.

#!/bin/bash
echo "---Start of Bash script---"

a=$1
echo "Argument from Perl script is" $a

To test, execute the perl script:

./perl-script.pl

 

Credits/References
https://stackoverflow.com/questions/3200801/how-can-i-call-a-shell-command-in-my-perl-script

How to fix print_req_error: I/O error, dev fd0, sector 0 error

After a fresh install of Ubuntu, my terminal was being flooded with “print_req_error: I/O error, dev fd0, sector 0” error.

dev fd0

This is because, your kernel thinks you have a floppy disk fd0, but cant find one. To fix this issue, you can run the following in your terminal:

sudo rmmod floppy
echo "blacklist floppy" | tee /etc/modprobe.d/blacklist-floppy.conf
sudo dpkg-reconfigure initramfs-tools

Misc: If you are deploying a new virtual machine, you can avoid this issue by deleting the Floppy Disk drive.

Source: StackOverflow