List shared or dynamic libraries required by a program

In Linux, the


is used to find out the shared libraries or dependencies required by a program if it is a dynamic executable. ldd requires the full path to the executable as input.

For instance, the Linux ps command depends on the following shared or dynamic libraries –

[root@kauai rtc0]# ldd $(which ps) =>  (0x00007ffeb6277000) => /lib64/ (0x0000003ef6200000) => /lib64/ (0x0000003ef4e00000) => /lib64/ (0x0000003ef4a00000) => /lib64/ (0x0000003ef5600000)
	/lib64/ (0x0000003ef4600000)

You can also use the ldd command to find out if an executable has an expected dependencies. In this case, we expect that the htpasswd, login and sshd commands depend on the crypt library as they prompt a user for a password for authentication purposes –

[root@kauai rtc0]# ldd $(which htpasswd) |grep crypt => /lib64/ (0x00007f010c8ab000)

[root@kauai rtc0]# ldd $(which login) | grep crypt => /lib64/ (0x0000003efd200000)

[root@kauai rtc0]# ldd $(which sshd) | grep crypt => /usr/lib64/ (0x00007ffb0b1f2000) => /lib64/ (0x00007ffb0a988000) => /lib64/ (0x00007ffb0a015000)

References –

Getting date from Real time clock (RTC) without using the date command or any other Linux time related commands.

In Linux, the “Real Time Clock” tracks wall clock time and is battery backed so that it works even with system power off. The RTC has no concept of time zone or daylight saving, it defaults to UTC. One of the user interfaces that the Linux Kernel exposes is


and we will use the files in that directory to directly read time related data from the RTC.

* Files –

[root@ns3 rtc0]# ls /sys/class/rtc/rtc0
date  dev  device  hctosys  max_user_freq  name  power  since_epoch  subsystem  time  uevent  wakealarm

* Date and time in UTC

[root@ns3 rtc0]# cat date
[root@ns3 rtc0]# cat time

* The maximum interrupt rate an unprivileged user may request from this RTC.

# cat max_user_freq

* The name of the RTC corresponding to this sysfs directory

[root@ns3 rtc0]# cat name

* The number of seconds since the epoch according to the RTC

[root@ns3 rtc0]# cat since_epoch

* Status information is reported through the pseudo-file /proc/driver/rtc

[root@ns3 rtc0]# cat /proc/driver/rtc
rtc_time        : 23:06:58
rtc_date        : 2015-01-19
alrm_time       : 01:00:02
alrm_date       : ****-**-**
alarm_IRQ       : no
alrm_pending    : no
24hr            : yes
periodic_IRQ    : no
update_IRQ      : no
HPET_emulated   : no
DST_enable      : no
periodic_freq   : 1024
batt_status     : okay

References –

Real Time Clock (RTC) Drivers for Linux

Update – Eritrean Ethiopian Internet radio

The server hosting the Internet radio for Eritrean and Ethiopian mostly Tigrigna music has been migrated to a new infrastructure and thus the public Internet IP address of the streaming radio has changed. Please use this URL to get the latest streaming address or save the below updated streaming playlist file –

Title1=Eritrean Ethiopian - Tigrigna

Download the stream playlist in Linux –

wget -O tigrigna-music.pls

Nginx / Apache – log real client IP or x-forwarded-for address.

Web servers such as Nginx or Apache when configured as reverse proxy behind a load balancer, they log the IP address of the load balancer in the access logs as the source IP. For practical use cases, you will usually want to log the actual client IP addresses.

In this setup, Nginx is setup to mimic a load balancer (reverse proxy) with multiple Apache web servers as backend.

1. Nginx snippet configuration to set x_forwarded_for proxy header –

server {
  listen 80;
  listen 443 default ssl;
  proxy_set_header Host $host;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

2. Apache snippet Configuration to capture x_forwarded_for header in the access logs –

<VirtualHost *:443>
    DocumentRoot /var/www/homenet
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" proxy
    SetEnvIf X-Forwarded-For "^.*\..*\..*\..*" forwarded
    CustomLog "logs/" combined env=!forwarded
    CustomLog "logs/" proxy env=forwarded

Before making the above custom changes , the logs showed the load balancer IP only – - - [19/Mar/2015:16:21:10 -0700] "GET /signup.php HTTP/1.0" 200 1237 - - [19/Mar/2015:16:21:11 -0700] "GET /login.php HTTP/1.0" 200 1715

After the change the client IP ( was logged – - - [19/Mar/2015:16:26:43 -0700] "GET / HTTP/1.0" 200 1311 "" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:35.0) Gecko/20100101 Firefox/35.0" - - [19/Mar/2015:16:26:44 -0700] "GET /signup.php HTTP/1.0" 200 1237 "" "Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:35.0) Gecko/20100101 Firefox/35.0"

References –

Google Chrome browse is not using my host DNS settings.

Environment –
Operating System : CentOS release 6.8
Google Chrome: Version 55.0.2883.87 (64-bit)

I have an Intranet DNS server with internal domain name. The domain name is resolved internally by my DNS server to an internal private IP address. With Firefox I could always visit my internal site without issues, but recently I installed Chrome browser into my CentOS desktop and when I tried to visit my internal site, it was directing me to an Internet site which I don’t own. Apparently Google Chrome was ignoring my dns setting and using its own name servers.

My first attempt – flush DNS on Chrome (failed)
I went to the DNS configuration for chrome and cleared host cache. The dns settings clearly showed my ‘nameservers’ as the (my internal name servers) and yet Chrome was not using it. Even after cleaning the host cache and flushing sockets, it didn’t help.

Chrome setting to view and manage DNS settings –


My second attempt – block IPv6 (worked)
After running tcpdump on port 53, Chrome was calling an IPv6 address 2001:4860:4860::8888 to resolve domains.

Added below lines to


in order to disable IPv6 temporarily for a test –

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

And executed the command

 sysctl -p 

to apply the new kernel settings. After this change and flushing dns, I was able to visit my internal site.

I am guessing the DNS IPs used by Chrome as somehow internally coded, and haven’t been able to find those settings.

References –

Free SSL certificates with Let’s Encrypt certbot – tested in Ubuntu 14.04 with Apache 2.

It is nice to have a site with valid SSL certificates, your visitors will be happy when they see that green padlock. Unfortunately it generally costs time and money to setup SSL certificates. Most big businesses with buy SSL certificates from well know Certificate Authorities(CAs) such as VeriSign, Symantec or GlobalSign. If you run a personal blog though and you can still get free SSL certificates.

Benefits of certificates –

a. Search engines such as Google give preference to secure sites
b. Security reasons – encryption and extended validation.

Disadvantages –

a. Introduces latency or delay
b. Operational cost to setup/renew certificates

One of the most popular SSL certificate providers was StarCom or StarSSL, until Google recently stopped trusting the certificates issues by this CA in Google Chrome. In the blog post, Google says –‘Google has determined that two CAs, WoSign and StartCom, have not maintained the high standards expected of CAs and will no longer be trusted by Google Chrome, in accordance with our Root Certificate Policy. ‘

So what is the alternative? Once my site was blocked by Chrome with a cert warning – ERR_CERT_AUTHORITY_INVALID – I did a research on new options and I can across “Let us encrypt”. And it was way better than StartSSL as it was easy to generate and renew certificates. Every thing was automated. No more certificate creation and renewal hassle.

Here are the steps I followed to get new certificates for my site –

1. Install certbot

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache

2. Get SSL certificates and modify Apache configuration automagically with certbot!!

root@localhost:~# certbot --apache

Interactive session –

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Enter email address (used for urgent renewal and security notices) (Enter 'c' to

Please read the Terms of Service at You must agree
in order to register with the ACME server at
(A)gree/(C)ancel: A

Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about EFF and
our work to encrypt the web, protect its users and defend digital rights.
(Y)es/(N)o: Y

Here, certbot automatically detects my domains –

Which names would you like to activate HTTPS for?
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):1,2,3,4

Obtaining a new certificate
Performing the following challenges:
tls-sni-01 challenge for
tls-sni-01 challenge for
tls-sni-01 challenge for
tls-sni-01 challenge for
Waiting for verification...
Cleaning up challenges
Deploying Certificate for to VirtualHost /etc/apache2/sites-available/danasmera-ssl
Deploying Certificate for to VirtualHost /etc/apache2/sites-available/danasmera-ssl
Deploying Certificate for to VirtualHost /etc/apache2/sites-available/linuxfreelancer-ssl
Deploying Certificate for to VirtualHost /etc/apache2/sites-available/linuxfreelancer-ssl

Please choose whether HTTPS access is required or optional.
1: Easy - Allow both HTTP and HTTPS access to these sites
2: Secure - Make all requests redirect to secure HTTPS access
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1

Congratulations! You have successfully enabled,,, and

You should test your configuration at:

- Congratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/ Your cert will
expire on 2017-09-08. To obtain a new or tweaked version of this
certificate in the future, simply run certbot again with the
"certonly" option. To non-interactively renew *all* of your
certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt:
Donating to EFF:

Just making sure my apache configuration is valid after certbot modified it –

root@localhost:~# apache2ctl -t
Syntax OK

certbot will create a ‘/etc/letsencrypt/live/’ directory and dump the SSL certificate, private key and cert chain in that directory –

SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
SSLCertificateChainFile /etc/letsencrypt/live/

Certbot created a multidomain SSL certiticate for 90 days, and a renewal cron job was added to my server so that I don’t have to do manual renewals –

root@localhost:~# cat /etc/cron.d/certbot
# /etc/cron.d/certbot: crontab entries for the certbot package
# Upstream recommends attempting renewal twice a day
# Eventually, this will be an opportunity to validate certificates
# haven't been revoked, etc.  Renewal will only occur if expiration
# is within 30 days.

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(3600))' && certbot -q renew

References –