Linux kernel – check the kernel options enabled during kernel compilation.

You might want to know whether a certain kernel option was enabled or not when your kernel was built, say if Symmetric multiprocessing (SMP) was enabled, or if KVM was compiled directly into the kernel or just as a loadable module. To answer this, you can look at the /boot/config-$(uname -r) file.

To find out if SMP is enabled in your system for instance, search for all SMP keywords in the kernel configuration –

daniel@linubuvma:~$ grep SMP /boot/config-$(uname -r)
CONFIG_X86_64_SMP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_SMP=y
# CONFIG_X86_VSMP is not set
# CONFIG_MAXSMP is not set
CONFIG_PM_SLEEP_SMP=y
CONFIG_SCSI_SAS_HOST_SMP=y
CONFIG_VIDEO_VP27SMPX=m

The ‘CONFIG_SMP=y’ setting indicates that the SMP module was compiled directly in the kernel, it is part of the monolithic kernel.

If your kernel was built with ‘CONFIG_IKCONFIG_PROC’, then the /proc/config.gz will contain the .config file the Linux kernel was compiled with.

daniel@linubuvma:~$ grep CONFIG_IKCONFIG_PROC  /boot/config-$(uname -r)
daniel@linubuvma:~$
daniel@linubuvma:~$ ls /proc/config.gz
ls: cannot access /proc/config.gz: No such file or directory

In my case, the kernel was not built with ‘CONFIG_IKCONFIG_PROC’.

curl – get only numeric HTTP response code

Most browsers have developer plugins where you can see the HTTP status code response and other request/response headers. For automation purposes though, you are most likely to use tools such as curl, httpie or python requests modules. In this post, we will see how to use curl for parsing HTTP response to get only the response code.

1. First attempt – use ‘-I’ option to fetch HTTP-header only.

The first line will show the response code.


daniel@linubuvma:~$ curl -I http://www.google.com
HTTP/1.1 200 OK
Date: Sun, 09 Apr 2017 06:45:00 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
domain=.google.com; Htty
Transfer-Encoding: chunked
Accept-Ranges: none
Vary: Accept-Encoding

But does this work all the time? No, some web services have problem with the HEAD HTTP request. Let us try amazon.com for instance –


daniel@linubuvma:~$ curl -I https://www.amazon.com
HTTP/1.1 503 Service Unavailable
Content-Type: text/html
Content-Length: 6450
Connection: keep-alive
Server: Server
Date: Sun, 09 Apr 2017 06:50:02 GMT
Set-Cookie: skin=noskin; path=/; domain=.amazon.com
Vary: Content-Type,Host,Cookie,Accept-Encoding,User-Agent
X-Cache: Error from cloudfront
Via: 1.1 a8dc63f9c2d878908bcd53ddc78da27f.cloudfront.net (CloudFront)


daniel@linubuvma:~$ curl -I -A "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12" https://www.amazon.com
HTTP/1.1 405 MethodNotAllowed
Content-Type: text/html; charset=ISO-8859-1
Connection: keep-alive
Server: Server
Date: Sun, 09 Apr 2017 06:49:47 GMT
Set-Cookie: skin=noskin; path=/; domain=.amazon.com
Strict-Transport-Security: max-age=47474747; includeSubDomains; preload
x-amz-id-1: N2RDV79SBB791BTYG2K8
allow: POST, GET
Vary: Accept-Encoding,User-Agent
X-Frame-Options: SAMEORIGIN
X-Cache: Error from cloudfront
Via: 1.1 f3459bfce7b7b7b8e8bfb19301f39bef.cloudfront.net (CloudFront)

In the first attempt, amazon.com was actually blocking automated checks by looking at the user-agent in the header, so i had to trick it by changing the user-agent header. The response code was 503. Once I changed the user-agent, I am getting 405 – the web server does not like our HEAD HTTP (‘-I’) option.

2. Second attempt – use ‘-w’ option to write-out specific parameter.

curl has ‘-w’ option for defining specific parameter to write out to the screen or stdout. Some of the variables are content_type, size_header, http_code. In our case, we are interested in http_code, which will dump the numerical response code from the last HTTP transfer. Let us try it –

daniel@linubuvma:~$ curl -I -s -w "%{http_code}\n" -o /dev/null http://www.google.com
200

We use ‘-I’ to get only the header and redirect the header to /dev/null and only print http_code to stdout. This is by far the most efficient way of doing it, as we are not transferring the whole page. If the ‘-I’ option does not work though, for sites such as amazon.com, we can drop ‘-I’ as follows –

daniel@linubuvma:~$ curl -s -w "%{http_code}\n" -o /dev/null -A "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12" https://www.amazon.com
200

This is very useful when are writing scripts to get only the HTTP status code.

References –

https://curl.haxx.se/docs/manpage.html
https://superuser.com/questions/272265/getting-curl-to-output-http-status-code

Linux share terminal in real time

How to share your terminal session with another user in real time.

Linux has a script command which is mainly used for ‘typescripting’ all output printed on terminal. Commands typed on a terminal and the resulting output can be written to a file for later retrieval.

One little known use of the script command is for sharing your terminal session with another user, this would particularly be useful for telecooperation say between a user and instructor. The instructor can lead the session by executing commands on the shell while the student would observe. Here is one way of doing this –

1. Instructor creates a named pipe using mkfifo

instructor@linubuvma:/$ mkfifo /tmp/shared-screen

instructor@linubuvma:/$ ls -al /tmp/shared-screen 
prw-rw-r-- 1 instructor instructor 0 Mar 31 00:08 /tmp/shared-screen

instructor@linubuvma:/$ script -f /tmp/shared-screen 

2. Student views the session in real time by reading the shared-screen file –

student@linubuvma:/tmp$ cat shared-screen
Script started on Fri 31 Mar 2017 12:09:42 AM EDT

As soon as the student runs the

cat shared-screen

command, the script command also gets started on the instructor’s session.

Whatever is typed on the instructor’s terminal will show up on the student’s screen and the student’s terminal will be restored as soon as the instructor exits or terminates the script session –

instructor@linubuvma:/$ free -m
             total       used       free     shared    buffers     cached
Mem:          3946       3572        374         40        288        996
-/+ buffers/cache:       2288       1658
Swap:         4092        195       3897
instructor@linubuvma:/$ exit
exit

Script done on Fri 31 Mar 2017 12:12:02 AM EDT
student@linubuvma:/tmp$

Note – the student’s screen will show the user id of the instructor at the bash prompt, as it is a replica of the instructors session. Once the instructor terminates the session, the student will get back to their original bash prompt.

References

http://man7.org/linux/man-pages/man1/script.1.html

Linux restricting user access

User administration: restricting access

1. With the chage command, an account expiration can be set. Once that date is reached, the user cannot log into the system interactively.
Let us run ‘chage’ interactively to set user’s account expiry –

[root@kauai /]# chage sshtest
Changing the aging information for sshtest
Enter the new value, or press ENTER for the default

	Minimum Password Age [0]: 
	Maximum Password Age [99999]: 
	Last Password Change (YYYY-MM-DD) [2015-11-04]: 
	Password Expiration Warning [7]: 
	Password Inactive [-1]: 
	Account Expiration Date (YYYY-MM-DD) [-1]: 2017-03-30

[root@kauai /]# chage -l sshtest
Last password change					: Nov 04, 2015
Password expires					: never
Password inactive					: never
Account expires						: Mar 30, 2017
Minimum number of days between password change		: 0
Maximum number of days between password change		: 99999
Number of days of warning before password expires	: 7

2. In addition to this, the usermod command can “lock” an account with the -L option. Say when a user is no longer with a company, the administrator may lock and expire an account with a single usermod command. The date must be given as the number of days since January 1, 1970. Setting the expiredate to 1 will immediately lock the account –

[student@serverX ~]$ sudo usermod -L -e 1 elvis

[student@serverX ~]$ sudo usermod -L elvis
[student@serverX ~]$ su - elvis
Password: elvis
su: Authentication failure

Locking the account prevents the user from authenticating with a password to the system. It is the recommended method of preventing access to an account by an employee who has left the company. If the employee returns, the account can later be unlocked with

usermod -U USERNAME

. If the account was also expired, be sure to also change the expiration date.

3. The nologin shell. Sometimes a user needs an account with a password to authenticate to a system, but does not need an interactive shell on the system.
For example, a mail server may require an account to store mail and a password for the user to authenticate with a mail client used to retrieve mail.
That user does not need to log directly into the system.

A common solution to this situation is to set the user’s login shell to /sbin/nologin. If the user attempts to log into the system directly,
the nologin “shell” will simply close the connection.

[root@serverX ~]# usermod -s /sbin/nologin student
[root@serverX ~]# su - student
Last login: Tue Feb  4 18:40:30 EST 2014 on pts/0
This account is currently not available.

References –

https://linux.die.net/man/1/chage
https://linux.die.net/man/1/chmod

Sort IP addresses numerically

Linux – Sort IPv4 addresses numerically

A novice user’s first attempt to sort a list of IP addresses would be to use ‘sort -n’, that is a numeric-sort option for sort command. Unfortunately, this will sort only the first quadrant of the IP address preceding the initial dot(‘.’). Definitely the GNU sort command does support sorting IPv4 addresses in numeric order, we just have to specify the right options.

Question to answer –

1. What is our delimiter for IPv4? dot.
2. What type of sorting? numeric.
3. How many fields? four.

Reading the man page for sort provides an option for each – 1) -t. 2) -n 3)-k
The third part might need clarification – since we have dot as a separator, the IP address will have four fields. We need to give sort a key specification (-k), with start and stop positions i.e to story by first quadrant(-k1,1), followed by second(-k2,2), followed by third(-k3,3) and finally by fourth(-k4,4).

The full command looks like this –

sort -t. -n -k1 -k2 -k3 -k4 /tmp/ipv4_file.txt

Let us use ForgeryPy to generate random Ipv4 addresses, we will write a simple python script to generate these random IPs to a file.

First install ForgeryPY –

pip install ForgeryPY

Script to generate IPv4 addresses –

$cat ipv4_generator.py

#!/usr/bin/env python

import forgery_py

uniq_ipv4=set()
for i in range(50):
    uniq_ipv4.add(forgery_py.internet.ip_v4())

with open('/tmp/ipv4_addresses.txt', 'w') as fp:
     for line in uniq_ipv4:
         fp.writelines(line+'\n')

Output –

daniel@linubuvma:/tmp$ cat /tmp/ipv4_addresses.txt
cat: /tmp/ipv4_addresses.txt: No such file or directory
daniel@linubuvma:/tmp$ python ipv4_generator.py
daniel@linubuvma:/tmp$ cat /tmp/ipv4_addresses.txt
222.21.147.97
187.234.9.45
144.101.36.131
31.192.196.59
24.16.131.84
8.52.22.181
17.40.228.224
58.164.169.156
234.78.147.45
254.150.145.225
167.111.243.3
168.168.248.227
68.104.225.196
55.138.152.3
223.30.151.183
235.245.57.76
226.122.222.107
176.199.0.130
13.68.133.125
14.157.155.254
11.155.170.92
249.0.112.141
228.209.60.62
246.130.20.235
113.17.65.20
120.76.166.133
81.191.49.37
17.226.209.151
81.184.136.140
9.172.35.65
129.205.96.54
181.130.8.142
21.78.73.162
5.216.102.88
91.140.115.96
134.140.243.193
177.148.152.60
175.37.63.212
60.175.123.112
176.250.114.170
54.62.22.255
182.78.64.216
238.92.143.140
181.206.65.80
11.139.192.62
38.158.146.36
241.236.161.184
30.223.32.242
233.107.53.70
36.222.68.164
daniel@linubuvma:/tmp$

Let us sort it –

daniel@linubuvma:/tmp$ sort -n -t. -k1,1 -k2,2 -k3,3 -k4,4 /tmp/ipv4_addresses.txt
5.216.102.88
8.52.22.181
9.172.35.65
11.139.192.62
11.155.170.92
13.68.133.125
14.157.155.254
17.40.228.224
17.226.209.151
21.78.73.162
24.16.131.84
30.223.32.242
31.192.196.59
36.222.68.164
38.158.146.36
54.62.22.255
55.138.152.3
58.164.169.156
60.175.123.112
68.104.225.196
81.184.136.140
81.191.49.37
91.140.115.96
113.17.65.20
120.76.166.133
129.205.96.54
134.140.243.193
144.101.36.131
167.111.243.3
168.168.248.227
175.37.63.212
176.199.0.130
176.250.114.170
177.148.152.60
181.130.8.142
181.206.65.80
182.78.64.216
187.234.9.45
222.21.147.97
223.30.151.183
226.122.222.107
228.209.60.62
233.107.53.70
234.78.147.45
235.245.57.76
238.92.143.140
241.236.161.184
246.130.20.235
249.0.112.141
254.150.145.225

Hope this help.

http://man7.org/linux/man-pages/man1/sort.1.html
https://pypi.python.org/pypi/ForgeryPy

How to be your own Certificate Authority(CA) with self signed certificates

This is a hands on tutorial on how you can setup your own Certificate Authority(CA) for internal network use. Once the CA certs are setup, you will generate certificate request(CSR) for your clients and sign them with your CA certs to create SSL certs for your internal network use. If you import your CA certs to your browser, you will be able to visit all internal sites using https without any browser warning, as long as the certs the your internal services are using are signed by your internal CA.

*Demo – Own CA for the home.net internal domain

1. Prepare certificate environment
and default parameters to use when creating CSR –

# mkdir /etc/ssl/CA
# mkdir /etc/ssl/newcerts
# sh -c "echo '100000' > /etc/ssl/CA/serial"
# touch /etc/ssl/CA/index.txt

# cat /etc/ssl/openssl.cnf
 dir		= /etc/ssl		# Where everything is kept
 database	= $dir/CA/index.txt	# database index file.
 certificate	= $dir/certs/home_cacert.pem 	# The CA certificate
 serial		= $dir/CA/serial 		# The current serial number
 private_key	= $dir/private/home_cakey.pem  # The private key
 default_days	= 1825			# how long to certify for
 default_bits		= 2048
 countryName_default		= US
 stateOrProvinceName_default	= California
 0.organizationName_default	= Home Ltd

2. Create self signed root certificate and install the root certificate and key

# openssl req -new -x509 -extensions v3_ca -keyout home_cakey.pem -out home_cacert.pem -days 3650
# mv home_cakey.pem /etc/ssl/private/
# mv home_cacert.pem /etc/ssl/certs/

3. Generate a CSR for the domain you want to issue a certificate –

# openssl genrsa -des3 -out home_server.key 2048
# openssl rsa -in home_server.key -out server.key.insecure
# mv server.key server.key.secure
# mv server.key.insecure server.key

4. Create the CSR now and generate a CA signed certificate

# openssl req -new -key server.key -out server.csr
# openssl ca -in server.csr -config /etc/ssl/openssl.cnf

Directory structure after signing and issuing certificates –

# ls -l /etc/ssl/CA/
total 24
-rw-r--r-- 1 root root 444 Aug 29 18:20 index.txt
-rw-r--r-- 1 root root  21 Aug 29 18:20 index.txt.attr
-rw-r--r-- 1 root root  21 Aug 29 18:16 index.txt.attr.old
-rw-r--r-- 1 root root 328 Aug 29 18:18 index.txt.old
-rw-r--r-- 1 root root   7 Aug 29 18:20 serial
-rw-r--r-- 1 root root   7 Aug 29 18:19 serial.old

# ls -l /etc/ssl/newcerts/
total 32
-rw-r--r-- 1 root root 4612 Aug 29 16:24 100000.pem
-rw-r--r-- 1 root root 4613 Aug 29 16:51 100001.pem
-rw-r--r-- 1 root root 4574 Aug 29 17:50 100002.pem
-rw-r--r-- 1 root root 4619 Aug 29 18:20 100003.pem

# cat /etc/ssl/CA/index.txt
V	190828202443Z		100000	unknown	/C=US/ST=California/O=Home Ltd/OU=Home/CN=www.home.net/emailAddress=daniel@home.net
V	190828205127Z		100001	unknown	/C=US/ST=California/O=Home Ltd/OU=Home/CN=wiki.home.net/emailAddress=daniel@home.net
V	190828215006Z		100002	unknown	/C=US/ST=California/O=Home Ltd/CN=home.net/emailAddress=daniel@home.net
V	190828222038Z		100003	unknown	/C=US/ST=California/O=Home Ltd/OU=Home/CN=homevm.home.net/emailAddress=daniel@home.net

# cat /etc/ssl/CA/serial
10411A

Now that you have your certificate, in this example /etc/ssl/certs/home_cacert.pem, you can import it to your web client such as a web browser, LDAP client etc.

References –

https://help.ubuntu.com/12.04/serverguide/certificates-and-security.html