Learn SSH: Config File

In this article series, I will explain how to use a command-line terminal to connect to secure shell (SSH) servers, using the config file for quick access to frequently used servers, and setting up an SSH server on macOS, Ubuntu, or CentOS.

Table of Contents:

– Introduction
– SSH CLI Commands
SSH Config File

SSH config file makes it easier to connect to frequently used servers. Here, I start with a simple server setup and then explain how to setup proxy jumps.

SSH config file is located in home directory under “.ssh” folder:

~/.ssh/config

For each server, add a block of text starting with “Host” followed by a memorable name for that server.

Host favorite_ssh

Add information like the address of the host on the following line with indentation:

Host favorite_ssh
        HostName ip_or_address_of_server
        User username_at_the_server

Now save the file. To connect to the sever, in a terminal window simply type ssh followed by the name you chose in the config file:

$ ssh favorite_ssh

This is equivalent of typing the following command:

$ ssh username_at_the_server@ip_or_address_of_server

You can add the identity file location to the config file as well:

Host favorite_ssh
        HostName ip_or_address_of_server
        User username_at_the_server
        IdentityFile ~/.ssh/my_private_key

which is equivalent of the following command:.

$ ssh username_at_the_server@ip_or_address_of_server -i ~/.ssh/my_private_key

You can add multiple servers to the config file:

Host favorite_ssh
        HostName ip_or_address_of_server
        User username_at_the_server
        IdentityFile ~/.ssh/my_private_key

Host favorite_ssh_2
        HostName ip_or_address_of_server_2 
        User username_at_the_server_2
        IdentityFile ~/.ssh/my_private_key_3

Host favorite_ssh_3
        HostName ip_or_address_of_server_3 
        User username_at_the_server_3
        IdentityFile ~/.ssh/my_private_key_3

You can add a proxy or jump server to the config file as well and use it to connect to your “favorite_ssh”:

Host proxy_1
        HostName ip_or_address_of_proxy_server
        User username_at_proxy_server
        IdentityFile ~/.ssh/proxy_server_private_key

Host favorite_ssh
        HostName ip_or_address_of_server
        User username_at_the_server
        IdentityFile ~/.ssh/my_private_key
        ProxyJump proxy_1

You can also use wildcards to use a same setting for a range of IP addresses (10.0.* and 10.1.0.*) :

Host proxy_1
        HostName ip_or_address_of_proxy_server
        User username_at_proxy_server
        IdentityFile ~/.ssh/proxy_server_private_key

Host 10.0.*
        User username_at_these_servers
        IdentityFile ~/.ssh/my_private_key_for_all_the_servers
        ProxyJump proxy_1


Host 10.1.0.*
        ProxyJump proxy_1

Now to connect to a server with IP address of 10.0.0.1, you can use the following command:

$ ssh 10.0.0.1

Or to connect to 10.1.0.2 with a username “my_user”, you can run:

$ ssh my_user@10.1.0.2

Let me know your questions and comments in the comment section.

Learn SSH: CLI Commands

In this article series, I will explain how to use a command-line terminal to connect to secure shell (SSH) servers, using the config file for quick access to frequently used servers, and setting up an SSH server on macOS, Ubuntu, or CentOS.

Table of Contents:

Introduction
SSH CLI Commands
SSH Config File

Establish SSH Connection

To SSH to a remote server with a username and password, type the following command in a terminal:

ssh username@server_address

You will be prompted for a password.

To SSH to a remote server with a private key, type the following command in a terminal:

ssh username@server_address -i ~/path/to/private/key

Replace ~/path/to/private/key with the actual path to your private key.

To connect to a remote server on a specific port, use the -p flag:

ssh username@server_address -p port_number

or

ssh username@server_address -i ~/path/to/private/key -p port_number

Replace port_number with the actual port number of the remote server.

Local Forward

To access a remote service, such as a database server on your local machine, you can use local port forwarding:

ssh -L localPort:server_address:remotePort username@server_address

For example, if the service you are trying to access locally is accessible on the remote server on port 5555, you can use the following command to get access to that service on a local port, such as 5657:

ssh -L 5657:server_address:5555 username@server_address

Now you can connect to the service using localhost:5657 or 127.0.0.1:5657.

Remote Forward

To access a local service on the remote server, you can use remote port forwarding:

ssh -R localPort:server_address:remotePort username@server_address
Jumpbox

To access a protected server through another accessible server, use the -j flag. Consider server_a as the jump box and server_b as the protected server, you’re trying to reach:

Local –> server_a –> server_b

ssh -J username_a@server_a username_b@server_b 

If you need to jump through more servers, try the following command:

Local –> server_a –> server_b –> server_c

ssh -J username_a@server_a,username_b@server_b username_c@server_c
Socks Proxy

To access the network and browse the private web pages on a remote server, you can create a SOCKS proxy. Choose a port number for your proxy, such as 8080, and create the link as:

ssh -D 8080 username@server_address

Now, set up a proxy on your local machine/browser to 127.0.0.1:8080 address and port.

Let me know your questions and comments in the comment section.

Next article in the series: SSH Config File

Install Python 3.7 on CentOS with all dependencies

In this post, I will go through installing Python 3.7 and all its dependencies on CentOS. Unlike Ubuntu, Python is not readily accessible using ‘yum’ package manager on CentOS. Therefore, we first need to install a few packages before installing Python.

$ sudo yum groupinstall -y "Development Tools"

$ sudo yum install –y gcc zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel tk-devel libffi-devel xz-devel gdbm-devel ncurses-devel db4-devel wget

Now that we installed all the dependencies, we need to download the latest Python from its website, https://www.python.org/downloads/:

$ wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz

Then, we need to extract the files from the archive and configure the installation:

$ tar -xzvf Python-3.7.4.tgz

$ sudo sh Python-3.7.4/configure --enable-optimizations

Finally, we run the following command to install Python:

$ sudo make altinstall

Your Python is now installed in the following folder: /usr/local/bin/

Optionally, you can make a link to access your Python using python3 command:

$ sudo ln -s /usr/local/bin/python3.7 /usr/bin/python3

$ sudo ln -s /usr/local/bin/pip3.7 /usr/bin/pip3

Note, if you cannot access Python by typing “python3”, you may need to add the following line to your .bashrc file:

export PATH=$PATH:/usr/local/bin/

Note: Your .bashrc is located in your home folder.

Now, disconnect and then connect back to your machine.

Please let me know if you had any questions or concerns in the comment section.

Learn SSH: Introduction to SSH on Unix-based systems

In this article series, I will explain how to use a command-line terminal to connect to secure shell (SSH) servers, using the config file for quick access to frequently used servers, and setting up an SSH server on macOS, Ubuntu, or CentOS.

Table of Contents:

Introduction
SSH CLI Commands
SSH Config File

So, what is SSH, and why we use it? SSH is a Transport layer protocol [source]. And, we use SSH to create secure tunnels between two machines, or a client and a server. For instance, we can run resource-demanding software on a server to speed up our work or deploy our website on it.

To get started, I recommend installing an Ubuntu server or CentOS minimal using Virtualbox on your computer. Then, open the following file with root privileges using your favorite text editor:

/etc/ssh/sshd_config

For instance, we can use vi to open the file:

$sudo vi /etc/ssh/sshd_config

This file is the configuration file for the SSH daemon on your virtual machine. Here, we need to make sure the following line is not commented out using ‘#’ and it is set to ‘yes’:

PasswordAuthentication yes

If we make any changes to this file, we need to restart the ssh service using the following command:

$sudo systemctl restart sshd

Now, we need to find our virtual machine’s IP address (host-only adaptor) to connect to it.

Now, we can open up a terminal on our computer (not inside the virtual machine!) and connect to our virtual machine using the username and password we set during server installation:

$ssh username@virtual_machine_IP_address

In my case, the result looks like this:

$ ssh sina@192.168.56.3
The authenticity of host '192.168.56.3 (192.168.56.3)' can't be established.
ECDSA key fingerprint is SHA256:MyF58hvhnjfyBHdQEl9fkpiGyGMG+b1W2LPfzpUQYu4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.56.3' (ECDSA) to the list of known hosts.
sina@192.168.56.3's password: 
Last login: Mon Aug 12 00:00:00 2019
[sina@localhost ~]$ 

Now, we are successfully connected to the virtual machine using SSH! We can run any command on the virtual machine using the terminal on our local computer.

Next article in the series: SSH CLI Commands

How to install Lapack on Mac OS?

This is a question I get asked a lot. Lapack is actually included in Accelerate library provided by Apple. You can include it in the header file of your C++ source code. Refer to this post for more information on how to use Lapack included in Accelerate.

If you like to use the latest version of Lapack, you can easily install it using Homebrew. Enter the following command in a terminal window to install Homebrew:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

To install Lapack libraries, you should first install GFortran which is included as a part of GCC. Run the following command in a terminal window:

brew install gcc

Now, you can simply install Lapack by typing the following command in a terminal window:

brew install lapack

Please let me know your questions in the comment section.

What is my gateway address?

Choosing a gateway address on Linux machines is an easy task to perform. Let’s consider a network consisting of three Linux machines as Figure 1 shows. 

Let’s consider following subnet and IP addresses:

Figure 1. Network Setup
  • Subnet 1: 10.0.0.0/24, IP Address 1: 10.0.0.1, and IP address 2: 10.0.0.2.
  • Subnet 2: 11.0.0.0/24 and IP Address 3: 11.0.0.1.
  • Subnet 3: 12.0.0.0/24 , IP Address 4: 12.0.0.1, and IP address 6: 12.0.0.2.
  • Subnet 4: 13.0.0.0/24 and IP Address 4: 13.0.0.1.

Run “route -n” command to check the current routes on each PC. Then use “ip route flush table main” command to clear the routing tables. Also, we need to enable IP forwarding on the routers.

Since PC 1 is only connected to subnet 1, we first add a route to subnet 1 using following command:

$ route add -net 10.0.0.0 netmask 255.255.255.0 gw 10.0.0.1

To connect PC 1 to other subnets on the network, we either need to add other subnets addresses to the routing table one by one or add a default gateway to send all the packets not intended for Subnet 1 to that gateway.

$ route add default gw 10.0.0.2

Similar to PC 1, we can add the routes to other PCs on the network based on the tables in Figure 1.

On PC 2:

$ route add -net 10.0.0.0 netmask 255.255.255.0 gw 10.0.0.2
$ route add -net 11.0.0.0 netmask 255.255.255.0 gw 11.0.0.1
$ route add -net 12.0.0.0 netmask 255.255.255.0 gw 12.0.0.1
$ route add -net 13.0.0.0 netmask 255.255.255.0 gw 13.0.0.1

And the default gateway is for all the packets to other networks which are not directly connected to PC 2:  

$ route add default gw 12.0.0.2

PC 3 is directly connected to Subnet 3, but it is not directly connected to Subnets 1, 2, and 4. To add the routes, we use the following commands:

$ route add -net 12.0.0.0 netmask 255.255.255.0 gw 12.0.0.2
$ route add -net 10.0.0.0 netmask 255.255.255.0 gw 12.0.0.1
$ route add -net 11.0.0.0 netmask 255.255.255.0 gw 12.0.0.1
$ route add -net 13.0.0.0 netmask 255.255.255.0 gw 12.0.0.1

Asymmetric Static Routing Network using Ubuntu Machines

In asymmetric routing, data packets take different paths to go from source to destination and to come back [source].  To set up an asymmetric network on Linux machines running Ubuntu 16.04, first, we need to configure the systems to act as routers. Let’s consider a network of 3 hosts and 3 routers as Figure 1 shows. The routers are going to be Linux systems bundled with several NICs.

Click on the image to enlarge it.
Figure 1. Network layout.

Figure 1. Network layout.

The routers should be able forward the packets from one network interface card’s (NIC) port to the others. In a terminal window, enter the following command under root privileges (only on routers):

sysctl net.ipv4.ip_forward=1

We also need to ensure that packets coming from a different path that they were sent to, are not dropped as well. Enter the following command (only on routers):

sysctl net.ipv4.conf.all.rp_filter=2

Now, we are ready to assign static routes to the machines. We consider the following subnets here:

  • The subnet for Host 1 connection to Router 1: 10.0.1.0/24
  • The subnet for Host 2 connection to Router 2: 10.0.2.0/24
  • The subnet for Host 3 connection to Router 3: 10.0.3.0/24
  • The subnet for Router 1 connection to Router 2: 10.0.4.0/24
  • The subnet for Router 1 connection to Router 3: 10.0.5.0/24
  • The subnet for Router 2 connection to Router 3: 10.0.6.0/24

Figure 2 shows the assigned IP address to each port of Linux machines.

Click on the image to enlarge it.

Figure 2. Assigned IP addresses to each port.

The only remaining step is to set up routing tables on each system. To assign routes to each machine we use the “route” command in terminal.

Hosts use their own assigned IP address for the gateway to their subnets and the IP address of next hop on the same subnet for the gateway to other networks. For example, Host 1 uses the gateway 10.0.1.2 for network 10.0.1.0 and the gateway 10.0.1.1 to connect to network 10.0.5.0.  We run the following commands for these two networks on Host 1:

route add -net 10.0.1.0 netmask 255.255.255.0 gw 10.0.1.2
route add -net 10.0.5.0 netmask 255.255.255.0 gw 10.0.1.1

We need to run the same command to add all the 6 subnets to every host and router on the network. Figure 3 shows the requires routing tables for each machine.

Click on the image to enlarge it.

Figure 3. Routing tables for each system. Now we can also add alternate routes to the same network with a higher metric (lower priority) using the “route” command. For example, we could add the following backup route to Router 2:

route add -net 10.0.3.0 netmask 255.255.255.0 gw 10.0.4.1 metric 100

We can test this route by running the ping command on a specific interface of  router 2:

ping 10.0.3.2 -I interface_connected_from_Router_2_to_Router_1

Let me know if you had any questions in the comment section.

MS SQL on MacOS: Connect to your database using Python

In this article series, I’ll review the tools and options to connect to an MS SQL server on macOS.

Table of contents:

Microsoft has released a beta version of its ODBC driver for macOS. Here is a quick and easy guide to connecting to your MS SQL using python.

The first thing you need is to install Homebrew.

Enter the following command in a terminal window to install Homebrew:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Afterward, enter the following commands in a terminal window to install Microsoft ODBC driver 13 for macOS:

brew tap microsoft/msodbcsql https://github.com/Microsoft/homebrew-msodbcsql-preview
brew update
brew install msodbcsql

Next item you need to install is pyodbc by entering the following command in a terminal:

pip install pyodbc

Now you have all the prerequisites to connect to your MS SQL database in python.

Now navigate to unixodbc folder using the following command:

cd /usr/local/Cellar/unixodbc/2.3.4

Here you have two files:

1-odbc.ini

2-odbcinst.ini

Open odbc.ini using the following command:

nano odbcinst.ini

There you will see the following information:

[ODBC Driver 13 for SQL Server]
Description=Microsoft ODBC Driver 13 for SQL Server
Driver=/usr/local/lib/libmsodbcsql.13.dylib
UsageCount=1

You need the copy the content in the square brackets which in my case is “ODBC Driver 13 for SQL Server”.

Exit the editor and open a new file like this:

nano ~/tempfile

Add the following lines to this file:

[MSSQL]
Description = Test to SQLServer
Driver = ODBC Driver 13 for SQL Server
Trace = No
Server = YourSQLServerAddress

Replace “ODBC Driver 13 for SQL Server” with the content you copied in the square brackets. Also, write your SQL server address instead of “YourSQLServerAddress“. Save the file and exit Nano editor.

Now, enter the following command in the terminal and enter your password:

sudo odbcinst -i -s -f ~/tempfile -l

To test your connection, open python editor and run the following script:

DSN is the name you used in the temp file. Replace yourUserName and yourPassWord with the ones you use for your SQL server.

You will see an output similar to:

<pyodbc.Connection object at 0xfffffffff>

MS SQL on macOS: Use Oracle SQL manager to access your database

In this article series, I’ll review the tools and options to connect to an MS SQL server on macOS.

Table of contents:

In order to connect to Azure SQL Database from MacOS (OS X) for free, you need two things:

1- Oracle SQL Developer (Download)
2- JTDS driver (Download)

Download these files and install Oracle SQL Developer. Then extract the JTDS driver zip file in a desired location (e.g., \Users\”Your User Name”\JTDS\).

Now open your Oracle SQL Developer and from the menu open preference as following figure shows:

SQL Developer

SQL Developer

From the Preference window, open Database > Third Party JDBC Drivers:

Click on the photo to open the full size image!

SQL Developer

SQL Developer

Here click on Add Entry and find your JTDS folder and choose jtds-1.3.1.jar as the driver path and click on Select and then OK.

Note: Before moving on from this part, make sure you have added your IP address in the firewall setting of your Azure Portal’s desired database.

Now you are ready to add your database to the program. From the connection pane on the left, click on the “+” button.

SQL Developer
SQL Developer

Now click on “SQLServer” tab and add your database connection information:

SQL Developer
SQL Developer

Click on connect. Don’t forget to retrieve your database here. Now save this profile. Now your database is ready to be inquired by transact SQL.

Next article: MS SQL on macOS: Connect to your database using Python