Setup OpenVPN

OpenVPN

If you want more than just pre-shared keys OpenVPN makes it easy to setup and use a Public Key Infrastructure (PKI) to use SSL/TLS certificates for authentication and key exchange between the VPN server and clients. OpenVPN can be used in a routed or bridged VPN mode and can be configured to use either UDP or TCP. The port number can be configured as well, but port 1194 is the official one. And it is only using that single port for all communication. VPN client implementations are available for almost anything including all Linux distributions, OS X, Windows and OpenWRT based WLAN routers.

Server Installation

To install openvpn in a terminal enter:

sudo apt install openvpn easy-rsa

Public Key Infrastructure Setup

The first step in building an OpenVPN configuration is to establish a PKI (public key infrastructure). The PKI consists of:

  • a separate certificate (also known as a public key) and private key for the server and each client, and

  • a master Certificate Authority (CA) certificate and key which is used to sign each of the server and client certificates.

OpenVPN supports bidirectional authentication based on certificates, meaning that the client must authenticate the server certificate and the server must authenticate the client certificate before mutual trust is established.

Both server and client will authenticate the other by first verifying that the presented certificate was signed by the master certificate authority (CA), and then by testing information in the now-authenticated certificate header, such as the certificate common name or certificate type (client or server).

Certificate Authority Setup

To setup your own Certificate Authority (CA) and generating certificates and keys for an OpenVPN server and multiple clients first copy the easy-rsa directory to /etc/openvpn. This will ensure that any changes to the scripts will not be lost when the package is updated. From a terminal change to user root and:

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

Next, edit /etc/openvpn/easy-rsa/vars adjusting the following to your environment:

export KEY_COUNTRY="US"
export KEY_PROVINCE="NC"
export KEY_CITY="Winston-Salem"
export KEY_ORG="Example Company"
export KEY_EMAIL="steve@example.com"
export KEY_CN=MyVPN
export KEY_ALTNAMES=AltMyVPN
export KEY_NAME=MyVPN
export KEY_OU=MyVPN


Enter the following to generate the master Certificate Authority (CA) certificate and key:

cd /etc/openvpn/easy-rsa/
source vars
./clean-all
./build-ca

Server Certificates

Next, we will generate a certificate and private key for the server:

./build-key-server myservername

As in the previous step, most parameters can be defaulted. Two other queries require positive responses, “Sign the certificate? [y/n]” and “1 out of 1 certificate requests certified, commit? [y/n]”.

Diffie Hellman parameters must be generated for the OpenVPN server:

./build-dh

All certificates and keys have been generated in the subdirectory keys/. Common practice is to copy them to /etc/openvpn/:

cd keys/
cp myservername.crt myservername.key ca.crt dh2048.pem /etc/openvpn/

Client Certificates

The VPN client will also need a certificate to authenticate itself to the server. Usually you create a different certificate for each client. To create the certificate, enter the following in a terminal while being user root:

cd /etc/openvpn/easy-rsa/
source vars
./build-key client1

Copy the following files to the client using a secure method:

  • /etc/openvpn/ca.crt

  • /etc/openvpn/easy-rsa/keys/client1.crt

  • /etc/openvpn/easy-rsa/keys/client1.key

As the client certificates and keys are only required on the client machine, you should remove them from the server.

Simple Server Configuration

Along with your OpenVPN installation you got these sample config files (and many more if if you check):

root@server:/# ls -l /usr/share/doc/openvpn/examples/sample-config-files/
total 68
-rw-r--r-- 1 root root 3427 2011-07-04 15:09 client.conf
-rw-r--r-- 1 root root 4141 2011-07-04 15:09 server.conf.gz

Start with copying and unpacking server.conf.gz to /etc/openvpn/server.conf.

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/server.conf.gz /etc/openvpn/
sudo gzip -d /etc/openvpn/server.conf.gz

Edit /etc/openvpn/server.conf to make sure the following lines are pointing to the certificates and keys you created in the section above.

ca ca.crt
cert myservername.crt
key myservername.key
dh dh2048.pem

Edit /etc/sysctl.conf and uncomment the following line to enable IP forwarding.

#net.ipv4.ip_forward=1

Then reload sysctl.

sudo sysctl -p /etc/sysctl.conf

That is the minimum you have to configure to get a working OpenVPN server. You can use all the default settings in the sample server.conf file. Now start the server. You will find logging and error messages in your via journal. Dependin on what you look for:

sudo journalctl -xe

If you started a templatized service openvpn@server you can filter for this particular message source with:

sudo journalctl --identifier ovpn-server

Be aware that the “systemctl start openvpn” is not starting your openvpn you just defined. Openvpn uses templatized systemd jobs, openvpn@CONFIGFILENAME. So if for example your configuration file is “server.conf” your service is called openvpn@server. You can run all kind of service and systemctl commands like start/stop/enable/disable/preset against a templatized service like openvpn@server.

ubuntu@testopenvpn-server:~$ sudo systemctl start openvpn@server

ubuntu@testopenvpn-server:~$ sudo systemctl status openvpn@server
. openvpn@server.service - OpenVPN connection to server
Loaded: loaded (/lib/systemd/system/openvpn@.service; enabled; vendor preset: enabled)
      Active: active (running) since Tue 2016-04-12 08:51:14 UTC; 1s ago
        Docs: man:openvpn(8)
              https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
              https://community.openvpn.net/openvpn/wiki/HOWTO
     Process: 1573 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writep
    Main PID: 1575 (openvpn)
       Tasks: 1 (limit: 512)
      CGroup: /system.slice/system-openvpn.slice/openvpn@server.service
              |-1575 /usr/sbin/openvpn --daemon ovpn-server --status /run/openvpn/server.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/server.conf --wr

Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: /sbin/ip route add 10.8.0.0/24 via 10.8.0.2
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: UDPv4 link local (bound): [undef]
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: UDPv4 link remote: [undef]
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: MULTI: multi_init called, r=256 v=256
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: IFCONFIG POOL: base=10.8.0.4 size=62, ipv6=0
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: ifconfig_pool_read(), in='client1,10.8.0.4', TODO: IPv6
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: succeeded -> ifconfig_pool_set()
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: IFCONFIG POOL LIST
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: client1,10.8.0.4
Apr 12 08:51:14 testopenvpn-server ovpn-server[1575]: Initialization Sequence Completed

You can enable/disable various openvpn services on one system, but you could also let Ubuntu do the heavy lifting. There is config for AUTOSTART in /etc/default/openvpn. Allowed values are “all”, “none” or space separated list of names of the VPNs. If empty, “all” is assumed. The VPN name refers to the VPN configutation file name. i.e. “home” would be /etc/openvpn/home.conf If you’re running systemd, changing this variable will require running “systemctl daemon-reload” followed by a restart of the openvpn service (if you removed entries you may have to stop those manually) After “systemctl daemon-reload” a restart of the “generic” openvon will restart all dependent services that the generator in /lib/systemd/system-generators/openvpn-generator created for your conf files when you called daemon-reload.

That is the minimum you have to configure to get a working OpenVPN server. You can use all the default settings in the sample server.conf file. Now start the server. You will find logging and error messages in your journal.

Now check if OpenVPN created a tun0 interface:

root@server:/etc/openvpn# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          inet addr:10.8.0.1  P-t-P:10.8.0.2  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
[...]

Simple Client Configuration

There are various different OpenVPN client implementations with and without GUIs. You can read more about clients in a later section. For now we use the OpenVPN client for Ubuntu which is the same executable as the server. So you have to install the openvpn package again on the client machine:

sudo apt install openvpn

This time copy the client.conf sample config file to /etc/openvpn/.

sudo cp /usr/share/doc/openvpn/examples/sample-config-files/client.conf /etc/openvpn/

Copy the client keys and the certificate of the CA you created in the section above to e.g. /etc/openvpn/ and edit /etc/openvpn/client.conf to make sure the following lines are pointing to those files. If you have the files in /etc/openvpn/ you can omit the path.

ca ca.crt
cert client1.crt
key client1.key

And you have to at least specify the OpenVPN server name or address. Make sure the keyword client is in the config. That’s what enables client mode.

client
remote vpnserver.example.com 1194

Also, make sure you specify the keyfile names you copied from the server

ca ca.crt
cert client1.crt
key client1.key

Now start the OpenVPN client:

ubuntu@testopenvpn-client:~$ sudo systemctl start openvpn@client
ubuntu@testopenvpn-client:~$ sudo systemctl status  openvpn@client
. openvpn@client.service - OpenVPN connection to client
   Loaded: loaded (/lib/systemd/system/openvpn@.service; disabled; vendor preset: enabled)
   Active: active (running) since Tue 2016-04-12 08:50:50 UTC; 3s ago
     Docs: man:openvpn(8)
           https://community.openvpn.net/openvpn/wiki/Openvpn23ManPage
           https://community.openvpn.net/openvpn/wiki/HOWTO
 Process: 1677 ExecStart=/usr/sbin/openvpn --daemon ovpn-%i --status /run/openvpn/%i.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/%i.conf --writep
Main PID: 1679 (openvpn)
   Tasks: 1 (limit: 512)
  CGroup: /system.slice/system-openvpn.slice/openvpn@client.service
          |-1679 /usr/sbin/openvpn --daemon ovpn-client --status /run/openvpn/client.status 10 --cd /etc/openvpn --script-security 2 --config /etc/openvpn/client.conf --wr

Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: OPTIONS IMPORT: --ifconfig/up options modified
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: OPTIONS IMPORT: route options modified
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: ROUTE_GATEWAY 192.168.122.1/255.255.255.0 IFACE=eth0 HWADDR=52:54:00:89:ca:89
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: TUN/TAP device tun0 opened
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: TUN/TAP TX queue length set to 100
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: do_ifconfig, tt->ipv6=0, tt->did_ifconfig_ipv6_setup=0
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: /sbin/ip link set dev tun0 up mtu 1500
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: /sbin/ip addr add dev tun0 local 10.8.0.6 peer 10.8.0.5
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: /sbin/ip route add 10.8.0.1/32 via 10.8.0.5
Apr 12 08:50:52 testopenvpn-client ovpn-client[1679]: Initialization Sequence Completed

Check if it created a tun0 interface:

root@client:/etc/openvpn# ifconfig tun0
tun0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  
          inet addr:10.8.0.6  P-t-P:10.8.0.5  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1

Check if you can ping the OpenVPN server:

root@client:/etc/openvpn# ping 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_req=1 ttl=64 time=0.920 ms

The OpenVPN server always uses the first usable IP address in the client network and only that IP is pingable. E.g. if you configured a /24 for the client network mask, the .1 address will be used. The P-t-P address you see in the ifconfig output above is usually not answering ping requests.

Check out your routes:

root@client:/etc/openvpn# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
10.8.0.5        0.0.0.0         255.255.255.255 UH        0 0          0 tun0
10.8.0.1        10.8.0.5        255.255.255.255 UGH       0 0          0 tun0
192.168.42.0    0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0         192.168.42.1    0.0.0.0         UG        0 0          0 eth0

Reference: https://help.ubuntu.com/lts/serverguide/openvpn.html

Advertisements

Iptables

Basic iptables howto

Iptables is a firewall, installed by default on all official Ubuntu distributions (Ubuntu, Kubuntu, Xubuntu). When you install Ubuntu, iptables is there, but it allows all traffic by default. Ubuntu 8.04 Comes with ufw – a program for managing the iptables firewall easily.

There is a wealth of information available about iptables, but much of it is fairly complex, and if you want to do a few basic things, this How To is for you.

Basic Commands

Typing

sudo iptables -L

lists your current rules in iptables. If you have just set up your server, you will have no rules, and you should see

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Basic Iptables Options

Here are explanations for some of the iptables options you will see in this tutorial. Don’t worry about understanding everything here now, but remember to come back and look at this list as you encounter new options later on.

  • -A – Append this rule to a rule chain. Valid chains for what we’re doing are INPUT, FORWARD and OUTPUT, but we mostly deal with INPUT in this tutorial, which affects only incoming traffic.

  • -L – List the current filter rules.

  • -m conntrack – Allow filter rules to match based on connection state. Permits the use of the --ctstate option.

  • --ctstate – Define the list of states for the rule to match on. Valid states are:

    • NEW – The connection has not yet been seen.
    • RELATED – The connection is new, but is related to another connection already permitted.
    • ESTABLISHED – The connection is already established.
    • INVALID – The traffic couldn’t be identified for some reason.
  • -m limit – Require the rule to match only a limited number of times. Allows the use of the --limit option. Useful for limiting logging rules.

    • --limit – The maximum matching rate, given as a number followed by “/second”, “/minute”, “/hour”, or “/day” depending on how often you want the rule to match. If this option is not used and -m limit is used, the default is “3/hour”.

  • -p – The connection protocol used.

  • --dport – The destination port(s) required for this rule. A single port may be given, or a range may be given as start:end, which will match all ports from start to end, inclusive.

  • -j – Jump to the specified target. By default, iptables allows four targets:

    • ACCEPT – Accept the packet and stop processing rules in this chain.

    • REJECT – Reject the packet and notify the sender that we did so, and stop processing rules in this chain.

    • DROP – Silently ignore the packet, and stop processing rules in this chain.

    • LOG – Log the packet, and continue processing more rules in this chain. Allows the use of the --log-prefix and --log-leveloptions.

  • --log-prefix – When logging, put this text before the log message. Use double quotes around the text to use.

  • --log-level – Log using the specified syslog level. 7 is a good choice unless you specifically need something else.

  • -i – Only match if the packet is coming in on the specified interface.

  • -I – Inserts a rule. Takes two options, the chain to insert the rule into, and the rule number it should be.

    • -I INPUT 5 would insert the rule into the INPUT chain and make it the 5th rule in the list.

  • -v – Display more information in the output. Useful for if you have rules that look similar without using -v.

  • -s --source – address[/mask] source specification

  • -d --destination – address[/mask] destination specification

  • -o --out-interface – output name[+] network interface name ([+] for wildcard)

Allowing Established Sessions

We can allow established sessions to receive traffic:

sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
  • The above rule has no spaces either side of the comma in ESTABLISHED,RELATED

If the line above doesn’t work, you may be on a castrated VPS whose provider has not made available the extension, in which case an inferior version can be used as last resort:

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Allowing Incoming Traffic on Specific Ports

You could start by blocking traffic, but you might be working over SSH, where you would need to allow SSH before blocking everything else.

To allow incoming traffic on the default SSH port (22), you could tell iptables to allow all TCP traffic on that port to come in.

sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT

Referring back to the list above, you can see that this tells iptables:

  • append this rule to the input chain (-A INPUT) so we look at incoming traffic
  • check to see if it is TCP (-p tcp). 
  • if so, check to see if the input goes to the SSH port (–dport ssh).
  • if so, accept the input (-j ACCEPT).

Lets check the rules: (only the first few lines shown, you will see more)

sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh

Now, let’s allow all incoming web traffic

sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

Checking our rules, we have

sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

We have specifically allowed tcp traffic to the ssh and web ports, but as we have not blocked anything, all traffic can still come in.

Blocking Traffic

Once a decision is made to accept a packet, no more rules affect it. As our rules allowing ssh and web traffic come first, as long as our rule to block all traffic comes after them, we can still accept the traffic we want. All we need to do is put the rule to block all traffic at the end.

sudo iptables -A INPUT -j DROP
sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

Because we didn’t specify an interface or a protocol, any traffic for any port on any interface is blocked, except for web and ssh.

Editing iptables

The only problem with our setup so far is that even the loopback port is blocked. We could have written the drop rule for just eth0 by specifying -i eth0, but we could also add a rule for the loopback. If we append this rule, it will come too late – after all the traffic has been dropped. We need to insert this rule before that. Since this is a lot of traffic, we’ll insert it as the first rule so it’s processed first.

sudo iptables -I INPUT 1 -i lo -j ACCEPT
sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www
DROP       all  --  anywhere             anywhere

The first and last lines look nearly the same, so we will list iptables in greater detail.

sudo iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere
    0     0 ACCEPT     all  --  any    any     anywhere             anywhere            state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:ssh
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere            tcp dpt:www
    0     0 DROP       all  --  any    any     anywhere             anywhere

You can now see a lot more information. This rule is actually very important, since many programs use the loopback interface to communicate with each other. If you don’t allow them to talk, you could break those programs!

Logging

In the above examples none of the traffic will be logged. If you would like to log dropped packets to syslog, this would be the quickest way:

sudo iptables -I INPUT 5 -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7

See Tips section for more ideas on logging.

Saving iptables

If you were to reboot your machine right now, your iptables configuration would disappear. Rather than type this each time you reboot, however, you can save the configuration, and have it start up automatically. To save the configuration, you can use iptables-save and iptables-restore.

Configuration on startup

WARNING: Iptables and NetworkManager can conflict. Also if you are concerned enough about security to install a firewall you might not want to trust NetworkManager. Also note NetworkManager and iptables have opposite aims. Iptables aims to keep any questionable network traffic out.NetworkManager aims to keep you connected at all times. Therefore if you want security all the time, run iptables at boot time. If you want security some of the time then NetworkManager might be the right choice.

WARNING: If you use NetworkManager (installed by default on Feisty and later) these steps will leave you unable to use NetworkManager for the interfaces you modify. Please follow the steps in the next section instead.

NOTE: It appears on Hardy, NetworkManager has an issue with properly on saving and restoring the iptable rules when using the method in the next section. Using this first method appears to work. If you find otherwise, please update this note.

Save your firewall rules to a file

sudo sh -c "iptables-save > /etc/iptables.rules"

At this point you have several options. You can make changes to /etc/network/interfaces or add scripts to /etc/network/if-pre-up.d/ and /etc/network/if-post-down.d/ to achieve similar ends. The script solution allows for slightly more flexibility.

Solution #1 – /etc/network/interfaces

(NB: be careful – entering incorrect configuration directives into the interface file could disable all interfaces, potentially locking you out of a remote machine.)

Modify the /etc/network/interfaces configuration file to apply the rules automatically. You will need to know the interface that you are using in order to apply the rules – if you do not know, you are probably using the interface eth0, although you should check with the following command first to see if there are any wireless cards:

iwconfig

If you get output similar to the following, then you do not have any wireless cards at all and your best bet is probably eth0.

lo        no wireless extensions.

eth0      no wireless extensions.

When you have found out the interface you are using, edit (using sudo) your /etc/network/interfaces:

sudo nano /etc/network/interfaces

When in the file, search for the interface you found, and at the end of the network related lines for that interface, add the line:

pre-up iptables-restore < /etc/iptables.rules

You can also prepare a set of down rules, save them into second file /etc/iptables.downrules and apply it automatically using the above steps:

post-down iptables-restore < /etc/iptables.downrules

A fully working example using both from above:

auto eth0
iface eth0 inet dhcp
  pre-up iptables-restore < /etc/iptables.rules
  post-down iptables-restore < /etc/iptables.downrules

You may also want to keep information from byte and packet counters.

sudo sh -c "iptables-save -c > /etc/iptables.rules"

The above command will save the whole rule-set to a file called /etc/iptables.rules with byte and packet counters still intact.

Solution #2 /etc/network/if-pre-up.d and ../if-post-down.d

NOTE: This solution uses iptables-save -c to save the counters. Just remove the -c to only save the rules.

Alternatively you could add the iptables-restore and iptables-save to the if-pre-up.d and if-post-down.d directories in the /etc/network directory instead of modifying /etc/network/interface directly.

NOTE: Scripts in if-pre-up.d and if-post-down.d must not contain dot in their names.

The script /etc/network/if-pre-up.d/iptablesload will contain:

#!/bin/sh
iptables-restore < /etc/iptables.rules
exit 0

and /etc/network/if-post-down.d/iptablessave will contain:

#!/bin/sh
iptables-save -c > /etc/iptables.rules
if [ -f /etc/iptables.downrules ]; then
   iptables-restore < /etc/iptables.downrules
fi
exit 0

Then be sure to give both scripts execute permissions:

sudo chmod +x /etc/network/if-post-down.d/iptablessave
sudo chmod +x /etc/network/if-pre-up.d/iptablesload

Solution #3 iptables-persistent

Install and use the iptables-persistent package.

Configuration on Startup for NetworkManager

NetworkManager includes the ability to run scripts when it activates or deactivates an interface. To save iptables rules on shutdown, and to restore them on startup, we are going to create such a script. To begin, press Alt+F2 and enter this command:

For Ubuntu:

gksudo gedit /etc/NetworkManager/dispatcher.d/01firewall

For Kubuntu:

kdesu kate /etc/NetworkManager/dispatcher.d/01firewall

Then, paste this script into your editor, save, and exit the editor.

if [ -x /usr/bin/logger ]; then
        LOGGER="/usr/bin/logger -s -p daemon.info -t FirewallHandler"
else
        LOGGER=echo
fi

case "$2" in
        up)
                if [ ! -r /etc/iptables.rules ]; then
                        ${LOGGER} "No iptables rules exist to restore."
                        return
                fi
                if [ ! -x /sbin/iptables-restore ]; then
                        ${LOGGER} "No program exists to restore iptables rules."
                        return
                fi
                ${LOGGER} "Restoring iptables rules"
                /sbin/iptables-restore -c < /etc/iptables.rules
                ;;
        down)
                if [ ! -x /sbin/iptables-save ]; then
                        ${LOGGER} "No program exists to save iptables rules."
                        return
                fi
                ${LOGGER} "Saving iptables rules."
                /sbin/iptables-save -c > /etc/iptables.rules
                ;;
        *)
                ;;
esac

Finally, we need to make sure NetworkManager can execute this script. In a terminal window, enter this command:

sudo chmod +x /etc/NetworkManager/dispatcher.d/01firewall

Tips

If you manually edit iptables on a regular basis

The above steps go over how to setup your firewall rules and presume they will be relatively static (and for most people they should be). But if you do a lot of development work, you may want to have your iptables saved everytime you reboot. You could add a line like this one in /etc/network/interfaces:

  pre-up iptables-restore < /etc/iptables.rules
  post-down iptables-save > /etc/iptables.rules

The line “post-down iptables-save > /etc/iptables.rules” will save the rules to be used on the next boot.

Using iptables-save/restore to test rules

If you edit your iptables beyond this tutorial, you may want to use the iptables-save and iptables-restore feature to edit and test your rules. To do this open the rules file in your favorite text editor (in this example gedit).

sudo sh -c "iptables-save > /etc/iptables.rules"
gksudo gedit /etc/iptables.rules

You will have a file that appears similiar to (following the example above):

# Generated by iptables-save v1.3.1 on Sun Apr 23 06:19:53 2006
*filter
:INPUT ACCEPT [368:102354]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [92952:20764374]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
-A INPUT -j DROP
COMMIT
# Completed on Sun Apr 23 06:19:53 2006

Notice that these are iptables commands minus the iptable command. Feel free to edit this to file and save when complete. Then to test simply:

sudo iptables-restore < /etc/iptables.rules

NOTE: With iptables 1.4.1.1-1 and above, a script allow you to test your new rules without risking to brick your remote server. If you are applying the rules on a remote server, you should consider testing it with:

sudo iptables-apply /etc/iptables.rules

After testing, if you have not added the iptables-save command above to your /etc/network/interfaces remember not to lose your changes:

sudo sh -c "iptables-save > /etc/iptables.rules"

More detailed Logging

For further detail in your syslog you may want create an additional Chain. This will be a very brief example of my /etc/iptables.rules showing how I setup my iptables to log to syslog:

# Generated by iptables-save v1.3.1 on Sun Apr 23 05:32:09 2006
*filter
:INPUT ACCEPT [273:55355]
:FORWARD ACCEPT [0:0]
:LOGNDROP - [0:0]
:OUTPUT ACCEPT [92376:20668252]
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -i eth0 -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -j LOGNDROP
-A LOGNDROP -p tcp -m limit --limit 5/min -j LOG --log-prefix "Denied TCP: " --log-level 7
-A LOGNDROP -p udp -m limit --limit 5/min -j LOG --log-prefix "Denied UDP: " --log-level 7
-A LOGNDROP -p icmp -m limit --limit 5/min -j LOG --log-prefix "Denied ICMP: " --log-level 7
-A LOGNDROP -j DROP
COMMIT
# Completed on Sun Apr 23 05:32:09 2006

Note a new CHAIN called LOGNDROP at the top of the file. Also, the standard DROP at the bottom of the INPUT chain is replaced with LOGNDROPand add protocol descriptions so it makes sense looking at the log. Lastly we drop the traffic at the end of the LOGNDROP chain. The following gives some idea of what is happening:

  • --limit sets the number of times to log the same rule to syslog

  • --log-prefix "Denied..." adds a prefix to make finding in the syslog easier

  • --log-level 7 sets the syslog level to informational (see man syslog for more detail, but you can probably leave this)

Disabling the firewall

If you need to disable the firewall temporarily, you can flush all the rules using

sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -F

or create a script using text editor such as nano

sudo nano -w /root/fw.stop
echo "Stopping firewall and allowing everyone..."
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT

Make sure you can execute the script

sudo chmod +x /root/fw.stop

You can run the script

sudo /root/fw.stop

Easy configuration via GUI

UFW & GUFW

GUFW – Gufw is a graphical frontend to UFW (Uncomplicated Firewall).

Cited from: https://help.ubuntu.com/community/IptablesHowTo

######################################################################

This is a small manual of iptables, I’ll show some basic commands, you may need to know to keep your computer secure.

Basic commands

List rules

iptables -L

This is going, list the default table “Filter”.

Edit: You may prefer to use iptables -L -vn to get more information, and to see ports as numbers instead of its names.

List rules in specific table

iptables -L -t nat

You can also list the other tables like: mangle, raw and security. You should consider reading a bit more about tables. You can do it in the Tables section in the man page of iptables

Delete all rules

iptables -F

Delete specific table liket nat

iptables -t nat -F

Specify chain policies

iptables let’s you configure default policies for chains in the filter table, where INPUT, FORWARD and OUTPUT, are the main ones (or at least the most used). Users can even define new chains.

These aforementioned chains, are better explained in this graph that comes from Wikipedia.

iptables chains

You can see the original image here

iptables -P INPUT DROP
iptables -P FORWARD ACCEPT
iptables -P OUTPUT DROP

You can define the default policy as ACCEPT and then deny specific traffic, or define default policies as DROPand then open specific traffic to and/or from your box. The last one is more secure, but require more job.

Block IP traffic from an specific IP or Network.

Block from an IP

iptables -A INPUT -s 11.22.33.44 -j DROP

If you want to block only on an specific NIC

iptables -A INPUT -s 11.22.33.44 -i eth0 -j DROP

Or an specific port

iptables -A INPUT -s 11.22.33.44 -p tcp -dport 22 -j DROP

Using a Network and not only one IP

iptables -A INPUT -s 11.22.33.0/24 -j DROP

Block traffic from a specific MAC address

Suppose you want to bloc traffic some a MAC address instead of an IP address. This is handy if a DHCP server is changing the IP of the maching you want to protect from.

iptables -A INPUT -m mac --mac-source 00:11:2f:8f:f8:f8 -j DROP

Block a specific port

If all you want is to block a port, iptables can still do it.

And you can block incoming or outgoing traffic.

Block incoming traffic to a port

Suppose we need to block port 21 for incoming traffic:

iptables -A INPUT -p tcp --destination-port 21 -j DROP

But if you have two-NIC server, with one NIC facing the Internet and the other facing your local private Network, and you only one to block FTP access from outside world.

iptables -A INPUT -p tcp -i eth1 -p tcp --destination-port 21 -j DROP

In this case I’m assuming eth1 is the one facing the Internet.

You can also block a port from a specific IP address:

iptables -A INPUT -p tcp -s 22.33.44.55 --destination-port 21 -j DROP

Or even block access to a port from everywhere but a specific IP range.

iptables -A INPUT p tcp -s ! 22.33.44.0/24 --destination-port 21 -j DROP

Block outgoing traffic to a port

If you want to forbid outgoing traffic to port 25, this is useful, in the case you are running a Linux firewall for your office, and you want to stop virus from sending emails.

iptables -A FORWARD -p tcp --dport 25 -j DROP

I’m using FORWARD, as in this example the server is a firewall, but you can use OUTPUT too, to block also server self traffic.

Log traffic, before taking action

If you want to log the traffic before blocking it, for example, there is a rule in an office, where all employees have been said not to log into a given server, and you want to be sure everybody obeys the rule by blocking access to ssh port. But, at the same time you want to find the one who tried it.

iptables -A INPUT -p tcp --dport 22 -j LOG --log-prefix "dropped access to port 22"
iptables -A INPUT -p tcp --dport 22 -j DROP

You will be able to see which IP tried to access the server, but of course he couldn’t.

Tips and Tricks

Because iptables executes the rules in order, if you want to change something you need to insert the rule in the specific position, or the desired effect is not going to be achieved.

List rules with numbers

iptables -nL --line-numbers

This is going to list all your rules with numbers preceding the rules. Determine where you want the inserted rule and write:

List specific chains

iptables -nL INPUT

Will list all INPUT rules.

iptables -nL FORWARD

Will list all OUTPUT rules

Insert rules

iptables -I INPUT 3 -s 10.0.0.0/8 -j ACCEPT

That is going to add a rule in position 3 of the “array”

Delete rules

iptables -D INPUT 3

That is going to remove the rule inserted above. You can also remove it, by matching it.

iptables -D INPUT -s 10.0.0.0/8 -j ACCEPT

Delete flush all rules and chains

This steps are very handy if you want to start with a completely empty and default tables:

iptables --flush
iptables --table nat --flush
iptables --table mangle --flush
iptables --delete-chain
iptables --table nat --delete-chain
iptables --table mangle --delete-chain

NOTE: do not execute this rules if you are connected via ssh or something similar, you may get locked out

Simple scripts for specific needs

How to stop brute force attacks

You can also use iptables to stop brute force attacks to your server, for example: Allow only three attempts to log through ssh before banning the IP for 15 minutes, this should let legitimate users to log to the servers, but bots will not be able. Remember to always use strong passwords

iptables -F
iptables -A INPUT -i lo -p all -j ACCEPT
iptables -A OUTPUT -o lo -p all -j ACCEPT                    
iptables -A INPUT -i eth0 -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport ssh -j ACCEPT
iptables -A INPUT -p tcp --dport www -j ACCEPT
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 22 -i eth0 -m state --state NEW -m recent --update --seconds 900 --hitcount 3 -j DROP
iptables -P INPUT DROP

How to NAT with iptables

iptables is also very useful to configure NAT routers, a Linux mashing can act as a router, and share its public IP with a private networks behind it. It is also useful to configure the DHCP in the same server.

To configure a NAT router, you will be better with a server with two NICs, let’s suppose you have:

  • eth0: 12.13.14.15
  • eth1: 10.1.1.1

Now configure NAT to forward all traffic from 10.1.1.0 network through eth0 IP. You may want to empty all tables and start with a fresh chains and tables (see how above).

iptables --table nat --append POSTROUTING --out-interface eth0 -j MASQUERADE
iptables --append FORWARD --in-interface eth1 -j ACCEPT

That is it, you only have to enable kernel forwarding now:

echo 1 > /proc/sys/net/ipv4/ip_forward

Cited from: https://www.garron.me/en/linux/iptables-manual.html

####################################################################

Iptables is an extremely flexible firewall utility built for Linux operating systems. Whether you’re a novice Linux geek or a system administrator, there’s probably some way that iptables can be a great use to you. Read on as we show you how to configure the most versatile Linux firewall.

About iptables

iptables is a command-line firewall utility that uses policy chains to allow or block traffic. When a connection tries to establish itself on your system, iptables looks for a rule in its list to match it to. If it doesn’t find one, it resorts to the default action.

iptables almost always comes pre-installed on any Linux distribution. To update/install it, just retrieve the iptables package:

sudo apt-get install iptables

There are GUI alternatives to iptables like Firestarter, but iptables isn’t really that hard once you have a few commands down. You want to be extremely careful when configuring iptables rules, particularly if you’re SSH’d into a server, because one wrong command can permanently lock you out until it’s manually fixed at the physical machine.

Types of Chains

iptables uses three different chains: input, forward, and output.

Input – This chain is used to control the behavior for incoming connections. For example, if a user attempts to SSH into your PC/server, iptables will attempt to match the IP address and port to a rule in the input chain.

Forward – This chain is used for incoming connections that aren’t actually being delivered locally. Think of a router – data is always being sent to it but rarely actually destined for the router itself; the data is just forwarded to its target. Unless you’re doing some kind of routing, NATing, or something else on your system that requires forwarding, you won’t even use this chain.

There’s one sure-fire way to check whether or not your system uses/needs the forward chain.

iptables -L -v

The screenshot above is of a server that’s been running for a few weeks and has no restrictions on incoming or outgoing connections. As you can see, the input chain has processed 11GB of packets and the output chain has processed 17GB. The forward chain, on the other hand, has not needed to process a single packet. This is because the server isn’t doing any kind of forwarding or being used as a pass-through device.

Output – This chain is used for outgoing connections. For example, if you try to ping howtogeek.com, iptables will check its output chain to see what the rules are regarding ping and howtogeek.com before making a decision to allow or deny the connection attempt.

The caveat

Even though pinging an external host seems like something that would only need to traverse the output chain, keep in mind that to return the data, the input chain will be used as well. When using iptables to lock down your system, remember that a lot of protocols will require two-way communication, so both the input and output chains will need to be configured properly. SSH is a common protocol that people forget to allow on both chains.

Policy Chain Default Behavior

Before going in and configuring specific rules, you’ll want to decide what you want the default behavior of the three chains to be. In other words, what do you want iptables to do if the connection doesn’t match any existing rules?

To see what your policy chains are currently configured to do with unmatched traffic, run the iptables -L command.

As you can see, we also used the grep command to give us cleaner output. In that screenshot, our chains are currently figured to accept traffic.

More times than not, you’ll want your system to accept connections by default. Unless you’ve changed the policy chain rules previously, this setting should already be configured. Either way, here’s the command to accept connections by default:

iptables --policy INPUT ACCEPT
iptables --policy OUTPUT ACCEPT
iptables --policy FORWARD ACCEPT

By defaulting to the accept rule, you can then use iptables to deny specific IP addresses or port numbers, while continuing to accept all other connections. We’ll get to those commands in a minute.

If you would rather deny all connections and manually specify which ones you want to allow to connect, you should change the default policy of your chains to drop. Doing this would probably only be useful for servers that contain sensitive information and only ever have the same IP addresses connect to them.

iptables --policy INPUT DROP
iptables --policy OUTPUT DROP
iptables --policy FORWARD DROP

Connection-specific Responses

With your default chain policies configured, you can start adding rules to iptables so it knows what to do when it encounters a connection from or to a particular IP address or port. In this guide, we’re going to go over the three most basic and commonly used “responses”.

Accept – Allow the connection.

Drop – Drop the connection, act like it never happened. This is best if you don’t want the source to realize your system exists.

Reject – Don’t allow the connection, but send back an error. This is best if you don’t want a particular source to connect to your system, but you want them to know that your firewall blocked them.

The best way to show the difference between these three rules is to show what it looks like when a PC tries to ping a Linux machine with iptables configured for each one of these settings.

Allowing the connection:

Dropping the connection:

Rejecting the connection:

Allowing or Blocking Specific Connections

With your policy chains configured, you can now configure iptables to allow or block specific addresses, address ranges, and ports. In these examples, we’ll set the connections to DROP, but you can switch them to ACCEPT or REJECT, depending on your needs and how you configured your policy chains.

Note: In these examples, we’re going to use iptables -A to append rules to the existing chain. iptables starts at the top of its list and goes through each rule until it finds one that it matches. If you need to insert a rule above another, you can use iptables -I [chain] [number] to specify the number it should be in the list.

Connections from a single IP address

This example shows how to block all connections from the IP address 10.10.10.10.

iptables -A INPUT -s 10.10.10.10 -j DROP

Connections from a range of IP addresses

This example shows how to block all of the IP addresses in the 10.10.10.0/24 network range. You can use a netmask or standard slash notation to specify the range of IP addresses.

iptables -A INPUT -s 10.10.10.0/24 -j DROP

or

iptables -A INPUT -s 10.10.10.0/255.255.255.0 -j DROP

Connections to a specific port

This example shows how to block SSH connections from 10.10.10.10.

iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -j DROP

You can replace “ssh” with any protocol or port number. The -p tcp part of the code tells iptables what kind of connection the protocol uses.  If you were blocking a protocol that uses UDP rather than TCP, then -p udp would be necessary instead.

This example shows how to block SSH connections from any IP address.

iptables -A INPUT -p tcp --dport ssh -j DROP

Connection States

As we mentioned earlier, a lot of protocols are going to require two-way communication. For example, if you want to allow SSH connections to your system, the input and output chains are going to need a rule added to them. But, what if you only want SSH coming into your system to be allowed? Won’t adding a rule to the output chain also allow outgoing SSH attempts?

That’s where connection states come in, which give you the capability you’d need to allow two way communication but only allow one way connections to be established. Take a look at this example, where SSH connections FROM 10.10.10.10 are permitted, but SSH connections TO 10.10.10.10 are not. However, the system is permitted to send back information over SSH as long as the session has already been established, which makes SSH communication possible between these two hosts.

iptables -A INPUT -p tcp --dport ssh -s 10.10.10.10 -m state --state NEW,ESTABLISHED -j ACCEPT

iptables -A OUTPUT -p tcp --sport 22 -d 10.10.10.10 -m state --state ESTABLISHED -j ACCEPT

Saving Changes

The changes that you make to your iptables rules will be scrapped the next time that the iptables service gets restarted unless you execute a command to save the changes.  This command can differ depending on your distribution:

Ubuntu:

sudo /sbin/iptables-save

Red Hat / CentOS:

/sbin/service iptables save

Or

/etc/init.d/iptables save

Other Commands

List the currently configured iptables rules:

iptables -L

Adding the -v option will give you packet and byte information, and adding -n will list everything numerically. In other words – hostnames, protocols, and networks are listed as numbers.

To clear all the currently configured rules, you can issue the flush command.

iptables -F

Cited from: https://www.howtogeek.com/177621/the-beginners-guide-to-iptables-the-linux-firewall/

How to use OpenVswitch with Docker

It is a known fact, that Docker uses linux bridge for container networking, by default.

When docker daemon starts, it creates a linux bridge named docker0, and assigns an IP address from the following range of private IP addresses. The containers gets assigned IP addresses from the same subnet.

“172.17.42.1/16”,  “10.0.42.1/16”, “10.1.42.1/16”, “10.42.42.1/16”, “172.16.42.1/24”, “172.16.43.1/24”, “172.16.44.1/24”, “10.0.42.1/24”, “10.0.43.1/24”, “192.168.42.1/24”, “192.168.43.1/24”, “192.168.44.1/24”.

The IP address, that gets assigned depends on IP addresses already in use by the docker host. For example, if none of the private IP addresses in the list above is in use by the docker host, then the docker daemon will assign docker0 the IP address 172.17.42.1, and the containers from same subnet (172.17.42.1/16). Note that IP allocation to the containers is handled by the docker daemon itself.

It’s also possible to use a different Linux bridge instead of the default docker0. The docker daemon needs to be started mentioning the same. All containers will then use that bridge for connectivity.

For normal usage Linux bridge is a good choice. However, there are cases, where OpenvSwitch (OVS) might be required instead of Linux bridge. For example, a single Linux bridge can only handle 1024 ports. This limits the scalability of docker as it won’t be possible to create more than 1024 containers, each having a single network interface. Another example is requirement of tunneling mechanism like GRE or VXLAN. But as of this writing, is not natively integrated with docker. There is an issue opened for the same- https://github.com/docker/docker/issues/8952

However, it is possible to use OVS for docker networking. Let’s see how.

First ,we need to understand what happens internally when a docker container is started.

This is what happens behind the scenes:

  1. Creation of veth pair
  2. Attaching one end of veth to the host bridge (docker0), and putting another end in container net namespace.
  3. Rename the veth end-point in container net namespace as ethX.
  4. IP address configuration for the containers

For Linux bridge, the steps are taken care by docker daemon itself, hence there is no user intervention required.

Logically, the relationship looks like the following:

 

docker-bridge

Since OVS is not yet integrated natively with docker, we have to perform the above steps manually.

Let’s go through the steps for a specific scenario of using OVS bridge ovsbr0 for docker containers. The instructions mentioned here are not architecture specific and works for both Intel and Power archs. My setup is a mix of Ubuntu 14.10 and 15.04 on Intel and Power KVM.

1. Create OVS bridge

[host]#ovs-vsctl add-br ovsbr0

2. Configure IP address

[host]#ip addr add dev ovsbr0 10.10.0.1/16
[host]#ip link set dev ovsbr0 up

Depending on your requirement, you might want to use DHCP. Accordingly, you might be required to setup a DHCP server. For example this is my DHCP server configuration on Ubuntu 15.04 LE (ppc64el) server.

[host]#cat /etc/default/isc-dhcp-server
INTERFACES="ovsbr0"
[host]#cat /etc/dhcp/dhcpd.conf
subnet 10.10.0.0 netmask 255.255.0.0 {
  range 10.10.0.2 10.10.0.254;
  option routers 10.10.0.1;
}

3. Create veth pair (veth_hostc0 – veth_contc0)

[host]# ip link add veth_hostc0 type veth peer name veth_contc0

4. Attaching one end of the veth pair (veth_hostc0) to host bridge (ovsbr0) and putting another end (veth_contc0) to the container net namespace.

Attach veth_hostc0 to ovsbr0

[host]# ovs-vsctl add-port ovsbr0 veth_hostc0

Create a container without default networking

[host]#docker run --net='none' -itd busybox /bin/sh
6a37777816a7073d1d238161e1f88d4a8e5032f26209b1dfacdaad69dea99606

Put veth_contc0 in the container net name space.

[host]#docker inspect -f '{{.State.Pid}}' 6a37777816a7
3975
[host]#mkdir -p /var/run/netns
[host]#ln -s /proc/3975/ns/net /var/run/netns/3975
[host]#ip link set veth_contc0 netns 3975

Check if the veth end point is available in the container net namespace.

[host]# docker attach 6a37777816a7
[container]# ifconfig -a
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

veth_contc0 Link encap:Ethernet  HWaddr 02:84:C7:43:7D:62  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:47 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4450 (4.3 KiB)  TX bytes:4450 (4.3 KiB)

5. Rename the veth end-point in container net namespace as ethX.

[host]#ip netns exec 3975 ip link set dev veth_contc0 name eth0
[host]#ip netns exec 3975 ip link set dev eth0 up

Check the device name inside the container

[host]# docker attach 6a37777816a7
[container]# ifconfig -a
eth0      Link encap:Ethernet  HWaddr 02:84:C7:43:7D:62  
          BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:47 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4450 (4.3 KiB)  TX bytes:4450 (4.3 KiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

6. IP address configuration for the containers

If static IP is used, then you would be required to set an IP for the container ethX interface explicitly. Otherwise, the container image needs to have a DHCP client (like dhclient, udhcpc) to get IP from the DHCP server.

Hope this gives you an idea on how to use OVS with docker.

Beyond few containers, you will soon realize, that the manual steps are too tedious to follow practically. You’ll need some automation.

Fortunately there is a way out, courtesy by @jpetazzo, who has written an excellent script to automate the entire process.

Download the script from https://github.com/jpetazzo/pipework.git

[host]#git clone https://github.com/jpetazzo/pipework.git

The manual set of steps mentioned above boils down to the following single command

[host]#pipework ovsbr0 -i eth0 $(docker run --net='none' busybox /bin/sh) dhcp

I have been using this to create 1000+ docker containers without any issues.

Cited From: http://cloudgeekz.com/400/how-to-use-openvswitch-with-docker.html

OAI Installation

System

ubuntu 14.04.5

kernel upgrade to 7.7.X

follow this link:

https://gitlab.eurecom.fr/oai/openairinterface5g/wikis/OpenAirKernelMainSetup

########

Notes for installing 4.7.x kernel from source with GTP module (TESTED)

sudo apt-get install xz-utils build-essential wget libncurses5-dev libssl-dev
sudo apt-get build-dep linux-image-$(uname -r) ncurses-bin
wget https://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.7.1.tar.xz
unxz linux-4.7.1.tar.xz
tar -xovf linux-4.7.1.tar
cd linux-4.7.1
# See Documentation/Changes for list of required minimum software to compile the kernel
make menuconfig #search for GTP option and enable it as a kernel module and save the kernel config file
# look for CONFIG_GTP in .config and make sure it is enabled as a kernel module CONFIG_GTP=m
make -j`nproc`
sudo make modules_install
sudo make install

###################################################

Install Docker CE

1. Build Container with Dockerfile

“Dockerfile”

FROM ubuntu:14.04.5

RUN apt-get update && apt-get install -y iputils-ping

RUN apt-get update && apt-get install -y sudo cmake make wget

CMD bash

####

docker build .

https://docs.docker.com/engine/reference/commandline/build/

2. docker run –rm -it –name=base base:v0 bash

3. Install mysql inside container: sudo apt-get install -y mysqlserver

4. Install OAI openair-cn, build hss/mme/spgw

mkdir openair5G 
cd openair5G
git clone https://gitlab.eurecom.fr/oai/openairinterface5g.git .
mkdir openair-cn
cd openair-cn
git clone https://gitlab.eurecom.fr/oai/openair-cn.git .

https://gloiremao.gitbooks.io/oai-tutorial/content/chapter2.html

5. Commit the running containers

#########

Reference

Install Docker CE

3.1) Update Repositories sudo apt-get update

3.2) Install default tools sudo apt-get install apt-transport-https \ ca-certificates \ curl \ software-properties-common

  1. Install Docker curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

sudo add-apt-repository \ "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable"

sudo apt-get update

sudo apt-get install docker-ce -y

4.1) Add user to Docker group sudo usermod -aG docker $USER exit

4.2) Check that Docker is installed properly

docker ps -a docker version

Basic Execution

Instructions:

  1. Pull the latest image docker pull moffzilla/oai-epc:v02
  2. Execute as follows: docker run --expose=1-9000 -p 3868:3868 -p 2152:2152 -p 2123:2123
    -it -h=epc --privileged=true --name oai-testing --cap-add=ALL -v
    /dev:/dev -v /lib/modules:/lib/modules moffzilla/oai-epc:v02
  3. Attach to the running container docker exec -it oai-testing /bin/bash
  4. Verify all EPC services are started

docker exec -it oai-testing /bin/bash

Verify sockets are listening:

netstat -na | grep 21

udp 0 0 192.171.11.1:2123 0.0.0.0:* LISTEN (MME_PORT_FOR_S11_MME)

udp 0 0 0.0.0.0:2152 0.0.0.0:* (SGW_IPV4_PORT_FOR_S1U_S12_S4_UP)

netstat -na | grep 3868

tcp 0 0 0.0.0.0:3868 0.0.0.0:* LISTEN (HSS)

tcp 0 0 127.0.0.1:3868 127.0.0.1:39554 ESTABLISHED ( S6A HSS <–> MME )

tcp 0 0 127.0.0.1:39554 127.0.0.1:3868 ESTABLISHED ( S6A MME <–> HSS )

cited from:

https://github.com/moffzilla/OAI-Docker

#############

 

How TreeSet Works Internally In Java

How TreeSet Works Internally In Java : TreeSet Interview Questions

We have already discussed difference between TreeSet and HashSet in java . The problem with java developers is that they know what TreeSet/TreeMap do but not  how. TreeSet is not frequently used collections framework class . So it is rare to get asked questions about this class  in the interview. Although , you should at least know when to prefer  TreeSet class  over other collection classes.

Read Also :  Difference between Iterator and ListIterator in Java with Example

What is TreeSet ?

TreeSet is like HashSet which contains the unique elements only but in a sorted manner. The major difference is that TreeSet provides a total ordering of the elements. The elements are ordered using their natural ordering, or by a Comparator typically provided at sorted set creation time. The set’s iterator will traverse the set in ascending element order.

How TreeSet works in Java ?

If you look into the TreeSet Api in rt.jar , you will find the following code :

    
  public class TreeSet<E>
              extends AbstractSet<E>
              implements NavigableSet<E>, Cloneable, java.io.Serializable

{
    private transient NavigableMap<E,Object> map;
    
    // Dummy value to associate with an Object in the backing Map
    
    private static final Object PRESENT = new Object();
    
    
    
    public TreeSet() {
        this(new TreeMap<E,Object>());
    }
    
    // SOME CODE ,i.e Other methods in TreeSet
    
    
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }   

    // SOME CODE ,i.e Other methods in TreeSet

}

According to TreeSet Oracle doc :

TreeSet is a NavigableSet implementation backed by TreeMap instance.


Hence , whenever you are adding element to the TreeSet object , it works just like HashSet , The only difference is that instead of HashMap here we have TreeMap object in the constructor.

As we know in TreeMap each key is unique as it internally uses HashMap . So what we do in the TreeSet is that we pass the argument in the add(Elemene E) that is E as a key in the TreeSet . Now we need to associate some value to the key , so what Java apis developer did is to pass the Dummy  value that is ( new Object () ) which is referred by Object reference PRESENT .

So , actually when you are adding a line in TreeSet like  treeset.add(3)   what java does internally is that it will put that element E here 3 as a key in the TreeMap(created during TreeSet object creation) and some dummy value that is Object’s object is passed as a value to the key .

Now if you see the code of the TreeMap put(Key k,Value V) method , you will find something like this

public V put(K key, V value) {
//Some code
}

The main point to notice in above code is that put (key,value) will return

1.  null , if key is unique and added to the map
2.  Old Value of the key , if key is duplicate

So , in TreeSet add() method ,  we check the return value of map.put(key,value) method with null value
i.e.

public boolean add(E e) {
return map.put(e, PRESENT)==null;
}

So , if map.put(key,value) returns null ,then
map.put(e, PRESENT)==null      will return true and element is added to the TreeSet.

So , if map.put(key,value) returns old value of the key ,then
map.put(e, PRESENT)==null      will return false and element is  not added to the TreeSet .

How to find the index of  any element in the TreeSet ?

There are many ways to find out the index of element in the TreeSet. Below is the one liner :

set.headSet(element).size()

Note  :  headSet(element) method returns the sub TreeSet(portion of TreeSet) whose values  are less than input element. Then we are calling size() method on the sub TreeSet , which returns the index of the element as sub TreeSet is already sorted.

Why and when we use TreeSet ?

We prefer TreeSet in order  to maintain the unique elements  in the sorted order .

What is the runtime performance of the add() method of the TreeSet and HashSet , where n represents the number of elements?

According to TreeSet Oracle doc :

TreeSet implementation provides guaranteed log(n) time cost for the basic operations (add, remove
and contains ) method.

According to HashSet Oracle doc :

HashSet provides constant time performance O(1) for basic operations  (add, remove and contains) method assuming the hash  function disperses the elements properly among the buckets.

One-liner :                TreeSet : O(log(n))  HashSet : O(1)

What is natural ordering in TreeSet ?

“Natural” ordering is the ordering implied by the implementation of Comparable interface by the objects in the TreeSet . Essentially RBTree must be able to tell which object is smaller than other object , and there are two  ways to supply that logic to the RB Tree implementation :

1. We need to implement the Comparable interface in the class(es) used as objects in TreeSet.
2. Supply an implementation of the Comparator would do comparing outside the class itself.


Why do we need TreeSet when we already had SortedSet ?

sortedSet is an interface while TreeSet is the class implementing it. As we know, in java, we can not create the objects of the interface. The class implementing the interface must fulfill the contract of interface, i.e , concrete class must implement all the methods present in the interface. TreeSet is such an implementation.

Which data structure you will prefer  in your code : HashSet and TreeSet ?

TreeSet contains the elements in the sorted order while HashSet is faster. Thus , deciding which one to choose depends upon the conditions :

If you want to maintain the order of the elements then TreeSet should be used because the result is alphabetically sorted.

If you do not want to sort the elements and  avoid duplicate elements . Your task involves mainly insert and retrieve operations then prefer HashSet.While iterating HashSet there is no ordering of elements while TreeSet iterates in the natural order.


What happens if the TreeSet is concurrently modified while iterating the elements ?

The iterator’s returned by the TreeSet class iterator method are fail-fast.  fail-fast means if the set is modified at any time after the iterator is created , in any way except the iterator’s own remove method  , the iterator will throw a ConcurrentModificationException. Thus , in the face of concurrent modification , the iterator fails quickly and cleanly . You can find it here  difference between fail-fast and fail-safe iterator in java with example.

Which copy technique (deep or shallow ) is used by TreeSet clone() method ?

According to Oracle docs , clone() method returns the shallow copy of the TreeSet instance.  In shallow copy , Both objects A and B shared the same memory location .


How to convert HashSet to TreeSet object ?

One-liner :   Set    treeObject = new TreeSet( hashSetObject);


What is the difference between HashSet and TreeSet in Java ?

I have already shared the difference between HashSet and TreeSet in Java with Example

Write an example of TreeSet ?

import java.util.TreeSet;


public class TreeSetExample {
    
    public static void main(String[] args) {
        TreeSet<String> treesetobj = new TreeSet<String>();
        treesetobj.add("Alive is awesome");
        treesetobj.add("Love yourself");
        System.out.println("TreeSet object output :"+ treesetobj);
 }
}

Output : 

 
TreeSet object output :[Alive is awesome, Love yourself]

Please mention in the comments in case you have any other questions regarding TreeSet class in java.

From

get mac address in python and shell

for Linux solution

INTERFACE_NAME = "eth0"

#######################################
def get_mac_id(ifname=INTERFACE_NAME):

import commands

words = commands.getoutput("ifconfig " + ifname).split()
if "HWaddr" in words:
    return words[ words.index("HWaddr") + 1 ]
else:
    return 'No MAC Address Found!'

Usage:

print get_mac_id(ifname="eth0")
######################

For Linux let me introduce a shell script that will show the mac address and allows to change it (MAC sniffing).

 ifconfig eth0 | grep HWaddr |cut -dH -f2|cut -d\  -f2
 00:26:6c:df:c3:95

Cut arguements may dffer (I am not an expert) try:

ifconfig etho | grep HWaddr
eth0      Link encap:Ethernet  HWaddr 00:26:6c:df:c3:95  

To change MAC we may do:

ifconfig eth0 down
ifconfig eth0 hw ether 00:80:48:BA:d1:30
ifconfig eth0 up
############
from uuid import getnode as get_mac
mac = get_mac()

 

Cited from

https://stackoverflow.com/questions/159137/getting-mac-address

NetworkConfigurationCommandLine/Automatic

Introduction

You can configure a network interface from the command line. You can configure your network client hosts with the command line by using commands to change your current settings or by editing a number of system files. This has several advantages over network managers in the GUI.

This guide had been developed for Ubuntu and Debian, other distributions can use a similar setup, but be aware that file locations may differ.

Requirements

An editor. This guide will use vi, but you can replace it with any other editor of your liking, gedit, nano, gvim, pico, emacs..

Have a working internet connection during the installation. We need to install packages and those are fetched from the online repositories.

Backup any files we touch. Just easier to recover when you have a backup.

Read this guide in full before actually configuring your network.

Basics

Setting/changing the hostname

The hostname command allows you to directly query, or set, the hostname from the command line.

You can see your current hostname by running hostname. To set the hostname directly you can run hostname newname as root. If you do this however, make sure you change the /etc/hosts file first. This is needed because otherwise you will need to boot into single user mode and change your hostname in /etc/hosts. This is because sudo requires DNS lookups in certain cases and it cannot resolve your newly set hostname.. To circumvent this you need to add the new name to the hosts file prior to setting the hostname and remove it once that action has succeeded.

sudo vi /etc/hosts
127.0.1.1 ubuntu newname

Set the hostname to newname.

sudo hostname newname
# or
echo newname | sudo tee /etc/hostname

Now you can remove the old hostname

sudo vi /etc/hosts
127.0.1.1 newname

When your system boots it will automatically read the hostname from the file /etc/hostnameYou can add hostname and IP addresses to the file /etc/hosts for static lookups.

Finding your network interface

When setting up your network you will need to know the network interface cards on your computer. The interface name of cards for different vendors may be different, which is why this step is needed.

ls /sys/class/net
# or
ip addr

This will list the interface names for all NICs on your computer. It will probably include eth0 (hardwired NIC), lo (loopback interface for the localhost), and something for your wireless card (like wifi0, or wlan0).

Disable network managers and/or wicd

Configuring your network via the CLI will likely interfere with Network Manager or wicd. To counter this, disable the startup script of either application or completely remove the packages. Be aware that the rest of this guide will require packages which need to be installed from the online repositories.

## Network manager
# Stop the current process
sudo /etc/init.d/NetworkManager stop
# Start: sudo /etc/init.d/NetworkManager start

# The inofficial way:
sudo chmod -x /etc/init.d/NetworkManager
# Reverse: sudo chmod +x /etc/init.d/NetworkManager
# The official way:
sudo update-rc.d -f NetworkManager remove
# Reverse: sudo update-rc.d -f NetworkManager defaults 50

# Or remove the network manager package.
sudo aptitude purge network-manager
# Reverse: sudo aptitude install network-manager

## wicd
# Stop the current process
sudo /etc/init.d/wicd stop
# Start: sudo /etc/init.d/wicd start

# The inofficial way:
sudo chmod -x /etc/init.d/wicd
# Reverse: sudo chmod +x /etc/init.d/wicd

# The official way:
sudo update-rc.d -f wicd remove
# Reverse: sudo update-rc.d -f wicd defaults 20

# Or remove the wicd package.
sudo aptitude purge network-manager
# Reverse: sudo aptitude install network-manager

Note: At some point Ubuntu started using upstart instead of the /sbin/init/ daemon. Thus if the first command above does not stop Network Manager, try this.

sudo stop network-manager

Configuring an interface

Word of wisdom

We will use eth0 in this example, your interface can be named differently, see Finding your network interface.

If you have disabled the either wicd or the network manager you probably don’t have a network connection anymore. Connect via a regular UTP cable to your router, and assuming you have DHCP enabled do the following:

sudo ip link set dev eth0 down
sudo dhclient eth0

This will bring your eth0 up by using DHCP. Your network is now configured (for the time being).

If you don’t have DHCP enabled configure your network by issueing the commands below, the gateway address is the IP address of your router. And your IP should be in the same range as the router is.

sudo ip addr add 192.168.1.14/24 dev eth0
sudo ip link set dev eth0 up
sudo ip route add default via 192.168.1.1

These commands configure your interface but these changes will not survive a reboot, since the information is not stored anyhwere. This is where the interfaces file comes in handy. To configure a interface permanently you’ll need to edit the interfaces file, /etc/network/interfaces.

sudo vi /etc/network/interfaces
## To configure a dynamic IP address
auto eth0
iface eth0 inet dhcp

## Or configure a static IP
auto eth0
iface eth0 inet static
  address 192.168.1.14
  gateway 192.168.1.1
  netmask 255.255.255.0
  network 192.168.1.0
  broadcast 192.168.1.255

For these settings to take effect you need to restart your networking services.

sudo /etc/init.d/networking restart

Setting up a second IP address or Virtual IP address

If you need to set up a second ip address you need to edit the /etc/network/interfaces.

sudo vi /etc/network/interfaces
auto eth0:1
iface eth0:1 inet static
  address 192.168.1.24
  netmask 255.255.255.0
  network 192.168.1.1
  broadcast 192.168.1.255
  gateway 192.168.1.1

For these new settings to take effect you need to restart networking services using the following command

sudo /etc/init.d/networking restart

Howto set MTU for a connection

You can set the MTU for an interface, you could do this by using the mtu keyword in the interface file or by using the ip link command.

iface eth0 inet dhcp
  # via mtu keyword
  mtu 1492
  # Via ip link command
  pre-up /sbin/ip link set $IFACE mtu 1492

The above example sets the MTU for device eth0 to 1492, the usual MTU for a PPPoE ISP connection. This however is only needed if connections seem to hang otherwise (with the default of 1500).

This tip was found on http://glasnost.beeznest.org/articles/290.

Setting up DNS

To cause your machine to consult with a particular server for name lookups you simply add their addresses to /etc/resolv.conf.

For example a machine which should perform lookups from the DNS server at IP address 192.168.1.1 would have a resolv.conf file looking like this

sudo vi /etc/resolv.conf

enter the following details

search example.com
domain example.com
nameserver 192.168.1.1

Wireless

We will not use un-encrypted wireless connections, but will make use of WEP/WPA/WPA2. Deviations from security/encryption method is an exercise left for the user. We also assume the network SSID is being broadcast.

Enabling wireless networking on your PC is pretty straight forward. If your network card is supported out of the box, then there are very little issues. If your card is not supported out of the box, you may need to use ndiswrapper, which will require the Windows drivers fo your card.

ndiswrapper

* Install a Windows driver with ndiswrapper for Dapper or ndiswrapper for 8.04 and up

# Ubuntu 6.06 (Dapper) and earlier
sudo aptitude install ndiswrapper-utils
# Ubuntu 8.04 and up (Hardy/Intrepid/Jaunty/Karmic)
sudo aptitude install ndiswrapper-utils-1.9

# All versions
sudo ndiswrapper -i /path/to/windows/driver.inf
sudo ndiswrapper -m
More information about ndiswrapper

https://help.ubuntu.com/community/WifiDocs/Driver/Ndiswrapper

ndiswrapper --help
man ndiswrapper

Configure your wireless interface

In the examples I will use wlan0 as your wireless card, this could be different on your machine! I will do the examples with a dynamic IP address (DHCP), the same principles applies to staticly configured IP’s.

Open the interfaces file

sudo vi /etc/network/interfaces
auto wlan0
iface wlan0 inet dhcp
pre-up  /etc/init.d/wpa.sh start
post-down /etc/init.d/wpa.sh stop

The pre-up command is run before the interface goes up. The post-down command is run after the interface goes down. There are also post-up and pre-down commands. E.g. You could use post-up to mount disks after an interface goes up. In this case we start wpa_supplicant before we enable the interface and we stop wpa_supplicant after we bring the interface down.

WPA supplicant

Before you start

(i) Before proceeding any further, it might be worthwhile to check whether your Wi-Fi Card is supported. Please see the wpa_supplicant websitefor more details. This will save you lots of time and frustration.

Install wpa_supplicant

sudo aptitude install wpasupplicant

Creating the password

You probably have given your wireless network a name (the ESSID or SSID), in this example we will use ubuntuwifi for our wireless network, our password will be OpenSesame. The SSID and password needs to be configured on your wireless router, how to do that is up to the reader. If you have problems coming up with a password, please have a look here.

If you are using WEP encryption (which is not advised) you may skip this step.

$ wpa_passphrase ubuntuwifi OpenSesame
network={
        ssid="ubuntuwifi"
        #psk="OpenSesame"
        psk=24f87a7583001eb7cea2394bbdb04eb2d3641f0b907dd31bd286be628c1841f8
}

Adding your network

Open the /etc/wpa_supplicant file and define your network.

sudo vi /etc/wpa_supplicant.conf
#
#  Please see /usr/share/doc/wpasupplicant/wpa_supplicant.conf.gz
#  for more complete configuration parameters.
#
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0

eapol_version=2
ap_scan=1
fast_reauth=1
country=NL

### Associate with any open access point
###  Scans/ESSID changes can be done with wpa_cli
network={
  ssid=""
  key_mgmt=NONE
  priority=1
}

# WEP
network={
  ssid="ubuntuwifi"
  scan_ssid=1
  key_mgmt=NONE
  wep_key0="OpenSesame"
  wep_key1="OpenOtherSesame"
  # Use the correct key..
  wep_tx_keyidx=0
  priority=5
}

# WPA/WPA2
network={
  ssid="ubuntuwifi"
  scan_ssid=1
  psk=24f87a7583001eb7cea2394bbdb04eb2d3641f0b907dd31bd286be628c1841f8
  priority=5
  ## The configuration items listed below do not need to be set, the defaults are
  ## pretty 'let us do it for you'.
  ## See /usr/share/doc/wpasupplicant/wpa_supplicant.conf.gz for more information.
  # key_mgmt=WPA-PSK
  # proto=WPA RSN
  # pairwise=CCMP TKIP
  # group=CCMP TKIP
}

Please beware, if you use WPA, remove the WEP section and vice versa.

The priority in this file determines to which network you will connect if more then 2 configured networks are available. This will always be the network with the highest priority.

WPA start script

Create the WPA startup script /etc/init.d/wpa.sh

sudo vi /etc/init.d/wpa.sh
#!/bin/bash
### BEGIN INIT INFO
# Provides:          wpa
# Required-Start:    $network $syslog $local_fs
# Required-Stop:     $network $syslog $local_fs
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start/stop script for wpa supplicant
# Description:       Custom start/stop script for wpa_supplicant.
### END INIT INFO

SELF=`basename $0`
WPA=wpa_supplicant
PROGRAM=/sbin/${WPA}
CONF=/etc/${WPA}.conf
INTERFACE=wlan0
DRIVER=wext
DAEMONMODE="-B"
LOGFILE=/var/log/$WPA.log

function start() {

    # TODO: Support multiple interfaces and drivers
    OPTIONS="-c $CONF -i $INTERFACE -D $DRIVER $DAEMONMODE"

    ## You can remove this if you are running 8.10 and up.
    # Ubuntu 8.10 and up doesn't need the -w anymore..
    # And the logfile option is not valid on 8.04 and lower
    local ver=$(lsb_release -sr | sed -e 's/\.//g');
    [ $ver -lt 810 ] && OPTIONS="$OPTIONS -w" && LOGFILE=""
    ##

    # Log to a file
    [ -n "$LOGFILE" ] && OPTIONS="$OPTIONS -f $LOGFILE"

    echo " * Starting wpa supplicant"
    eval $PROGRAM $OPTIONS
}

function stop() {
    echo " * Stopping wpa supplicant"
    wpa_cli -i $INTERFACE terminate
    #pkill $PROGRAM ## alternative method 
}

function debug() {
    stop
    DAEMONMODE="-ddd"
    start
}

function restart() {
    stop
    start
}

function status() {
    pgrep -lf $PROGRAM
}

function usage() {
    echo "Usage: $SELF <start|stop|status|debug>"
    return 2
}

case $1 in
    start|stop|debug|restart|status) $1 ;;
    *) usage ;;
esac

Make the start script executable.

sudo chmod +x /etc/init.d/wpa.sh

You can now start WPA supplicant as a service or in debugging mode:

# Service
/etc/init.d/wpa.sh start
# Debugging
/etc/init.d/wpa.sh debug

Make sure the script gets run on boot and stopped at shutdown

sudo update-rc.d wpa.sh defaults

With wpa_cli you can make changes to your wpa_supplicant config file and reload these changes:

sudo wpa_cli

Enter help to see what you can do with wpa_cli. Some of the options are: reconfigure, disconnect, reconnect, reassociate. These options speak for themself.

For more information about wpa_supplicant, please have a look at their respective manpages:

man wpa_supplicant
man wpa_supplicant.conf
man wpa_cli
man wpa_gui # Only when you have installed the wpagui package
gzip -dc /usr/share/doc/wpasupplicant/wpa_supplicant.conf.gz | less

Now that you have setup everything, you can try to connect to your network by restarting networking

sudo /etc/init.d/networking restart

You could also reboot your machine if you prefer that.

Configure laptops for multiple locations

When you have a laptop you don’t want to configure it to only be able to have a internet connection at only one location. You probably go to work and use a wired connection, you goto to coffeeshop and use the wifi hotspot overthere and at home you have another network configuration. That is exactly what we are going to configure now.

Guessnet, ifplugd and wpa_supplicant

Install guessnet and ifplugd

sudo aptitude install guessnet ifplugd

Configure ifplugd. Define which interfaces need to be hotplug and adjust the arguments. You should remove the -q.

sudo vi /etc/default/ifplugd
# Just an example
INTERFACES="eth0 wlan0"
#ARGS="-q -f -u0 -d10 -w -I"
ARGS="-f -u0 -d10 -w -I"
# Override ARGS for a particular interface
# This is for an Intel Corporation PRO/Wireless 3945ABG [Golan] Network Connection (rev 02)
ARGS_wlan0="-F -u0 -d10 -w -I"
SUSPEND_ACTION=stop

Some cards do not really play well with the defaults of Ubuntu, adjust where needed.

More information for ifplugd

See ifplugd for more information. And their respective man pages

man ifplugd
man ifplugd.conf

You will need the wpa.sh script mentioned earlier in this guide and you will need to make sure it will be started and stopped:

# Start wpa_supplicant at boot
sudo ln -s /etc/init.d/wpa.sh /etc/rc2.d/S19wpa
sudo ln -s /etc/init.d/wpa.sh /etc/rc3.d/S19wpa

# Kill wpa_supplicant at shutdown
sudo ln -s /etc/init.d/wpa.sh /etc/rc5.d/K21wpa
sudo ln -s /etc/init.d/wpa.sh /etc/rc6.d/K21wpa

Map your physical interfaces to logical interfaces

First, we are going to make a mapping for eth0 and wlan0 and said which mapped interface could be used for each physical interface:

mapping eth0
  # Tell ifupdown to use guessnet to determine which network we can use
  script guessnet-ifupdown
  # Default location
  map default: missing-cable
  # How verbose we are
  map verbose: false
  map debug: false
  # Our different networks, order decides which network is picked
  # if two or more networks are available at the same time.
  map officelan homelan aruba missing-cable

mapping wlan0
  script guessnet-ifupdown
  map default: missing-cable
  map verbose: false
  map debug: false
  map workwifi homewifi wifi-open missing-cable

Normally ifupdown configures the interfaces, but now we’ve told it to use guessnet to determine the network being used.

Define tests to select networks

As you will see with the officelan, homelan and aruba examples below we will execute tests to see wheter a peer is present based on the MAC address. The simplest solution for this is to check whether your gateway is present. You can find out the MAC address of your gateway by running the ip neigh command. You need to be connected with your network for this.

$ ip neigh
192.168.1.254 dev eth0 lladdr 00:24:17:47:xx:xx

This my default gateway, has IP address 192.168.1.254 and 00:24:17:47:xx:xx as a MAC address. This gives us the needed information to define the test.

  test peer address 192.168.1.254 mac 00:24:17:47:xx:xx source 192.168.1.14

You don’t need to specify the source IP address, but in certain cases this is required. I always add it so I don’t have to worry about it in case I do need it.

So let’s define our fixed networks using the peer tests:

# Work
# Obfuscated some details about my work enviroment
iface officelan inet static
  # Test to see if our gateway is present with MAC address 00:00:xx:xx:xx:xx
  # from source address 194.134.x.x
  test peer address 194.134.x.x mac 00:00:xx:xx:xx:xx source 194.134.x.x
  address 194.134.x.x
  netmask 255.255.255.0
  gateway 194.134.x.x
  # Set our DNS, this is used by the resolvconf package
  dns-domain euronet.nl
  dns-search euronet.nl orange.nl wanadoo.nl online.nl euro.net
  dns-nameservers 194.134.5.5 194.134.0.97
  # (post|pre)-(up|down) actions, which are optional
  # Mount samba shares at work after we brought the interface up
  post-up /home/my_user/bin/mount_smb start
  # And disable to mounts before we shut the interface down
  pre-down /home/my_user/bin/mount_smb stop
  # Which interface has preference, eth0 or wlan0, this is needed if you
  # are connected via both interfaces.
  metric 1

# One happy island (very nice weather ;))
iface aruba inet dhcp
  test peer address 192.168.1.1 mac 00:08:5C:89:xx:xx source 192.168.1.4
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl euro.net

# Home
iface homelan inet static
  test peer address 192.168.1.254 mac 00:24:17:47:xx:xx source 192.168.1.14
  address 192.168.1.14
  netmask 255.255.255.0
  gateway 192.168.1.1
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl euro.net
  dns-nameservers 194.134.5.5 194.134.0.97
  # At home, wireless has precedence over our fixed network
  metric 2

For wireless networks you can also use the peer test, but there is a simpler way to see if you can connect to a wireless network. Test to see if the ESSID is present:

  test wireless essid ubuntuwifi
  # In case of spaces in the ESSID
  test wireless essid "ubuntu wifi"
Spaces in the ESSID
In older versions of guessnet you didn’t need to use quotes around the ESSID, but later versions do require it.
# Wifi at work
iface workwifi inet dhcp
  # Use this if we can find Online Wireless network
  test wireless essid "Online Wireless"
  dns-domain euronet.nl
  dns-search euronet.nl orange.nl wanadoo.nl online.nl sf6800.euronet.nl euro.net
  dns-nameservers 194.134.5.5 194.134.0.97
  # This interface has a lesser precedence over eth0
  metric 2

# Wifi at home
iface homewifi inet static
  test wireless essid ubuntuwifi
  address 192.168.1.114
  netmask 255.255.255.0
  gateway 192.168.1.1
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl
  dns-nameservers 194.134.5.5 194.134.0.97
  # This interface is used in case we are both connected via wifi and
  # wired LAN
  metric 1

# Connect to any open network
iface wifi-open inet dhcp
  # Any ESSID is valid
  wireless-essid any
  # Is the wireless work open? Yes, then use this mapping
  test wireless open
  # Set the DNS
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl
  dns-nameservers 194.134.5.5 194.134.0.97

To see what kind of other test you can run to determine which network you are in, please have a look at the manpage of guessnet.

man guessnet

Use of metrics

Some of you might have noticed a metric statement for some of the interfaces. I do this because when you are connected via both wireless and wired networks, some things may go “bad” with the routing table. When you define a metric for these two interfaces you will tell the routing table which interface has preference over the other. The lowest metric has priority over the higher metric.

Or as I explained in a ubuntuforum post: The problem is that without the metric you will have 2 interfaces used for the same destinations. It will use either interface, which causes problems with the routing table.

By setting a metric you can avoid this, since the higher metric is more “expensive” to use. So the OS will use the interfaces with the lowest metric if it needs to route traffic. In case the lower metric interface is shutdown it will use the higher metric interface since it is the only interface which can be used to route traffic towards that particular network/destination.

See also http://en.wikipedia.org/wiki/Metrics_%28networking%29

The problem could also be solved by adding static routes, but that is used mostly to make sure specific networks/hosts are routed via a different interface then the default. You then force only those hosts to use link B even though normally the OS would use link A.

Result

When we put all the configuration segments together you will get a interfaces file which looks like this

auto lo
iface lo inet loopback
address 127.0.0.1
netmask 255.0.0.0

mapping eth0
  script guessnet-ifupdown
  map default: missing-cable
  map verbose: false
  map debug: false
  map officelan homelan aruba missing-cable

mapping wlan0
  script guessnet-ifupdown
  map default: missing-cable
  map verbose: false
  map debug: false
  map workwifi homewifi wifi-open missing-cable

# Work
iface officelan inet static
  test peer address 194.134.x.x mac 00:00:xx:xx:xx:xx source 194.134.x.x
  address 194.134.x.x
  netmask 255.255.255.0
  gateway 194.134.x.x
  dns-domain euronet.nl
  dns-search euronet.nl orange.nl wanadoo.nl online.nl euro.net
  dns-nameservers 194.134.5.5 194.134.0.97
  post-up /home/my_user/bin/mount_smb start
  pre-down /home/my_user/bin/mount_smb stop
  metric 1

# One happy island (very nice weather ;))
iface aruba inet dhcp
  test peer address 192.168.1.1 mac 00:08:5C:89:xx:xx source 192.168.1.4
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl euro.net

# Home
iface homelan inet static
  test peer address 192.168.1.254 mac 00:24:17:47:xx:xx source 192.168.1.14
  address 192.168.1.14
  netmask 255.255.255.0
  gateway 192.168.1.1
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl euro.net
  dns-nameservers 194.134.5.5 194.134.0.97
  metric 2

# Wifi at work
iface workwifi inet dhcp
  # Use this if we can find Online Wireless network
  test wireless essid "Online Wireless"
  dns-domain euronet.nl
  dns-search euronet.nl orange.nl wanadoo.nl online.nl sf6800.euronet.nl euro.net
  dns-nameservers 194.134.5.5 194.134.0.97
  # This interface has a lesser precedence over eth0
  metric 2

# Wifi at home
iface homewifi inet static
  test wireless essid ubuntuwifi
  address 192.168.1.114
  netmask 255.255.255.0
  gateway 192.168.1.1
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl
  dns-nameservers 194.134.5.5 194.134.0.97
  # This interface is used in case we are both connected via wifi and
  # wired LAN
  metric 1

# Connect to any open network
iface wifi-open inet dhcp
  # Any ESSID is valid
  wireless-essid any
  # Is the wireless work open? Yes, then use this mapping
  test wireless open
  # Set the DNS
  dns-domain opperschaap.net
  dns-search opperschaap.net euronet.nl wanadoo.nl online.nl
  dns-nameservers 194.134.5.5 194.134.0.97

You can now test if it all works like intended.

/etc/init.d/networking stop
/etc/init.d/wpa.sh stop
/etc/init.d/ifplugd stop

If you enter ip addr you will only see the lo interface being active.

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000

And start all the required daemons:

/etc/init.d/ifplugd start
/etc/init.d/wpa.sh start
/etc/init.d/networking start

And now you will see your interfaces configured properly

$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN 
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000

Done.

Bonus script

This script will be a stop/start script for your complete network, which can be used when you want to enable networking after you have suspended your laptop or for other reasons

INT="eth0 wlan0"

stop() {
    /etc/init.d/networking stop
    /etc/init.d/wpa.sh stop
    /etc/init.d/ifplugd stop
    for i in $INT ; do
        ip link set dev "$i" down &>/dev/null
    done

}

start() {
    /etc/init.d/ifplugd start
    /etc/init.d/wpa.sh start
    /etc/init.d/networking start
}

restart() {
    stop
    sleep 5
    start
}

$1

Cited from: https://help.ubuntu.com/community/NetworkConfigurationCommandLine/Automatic

How To Install and Use Docker on Ubuntu 16.04

Introduction

Docker is an application that makes it simple and easy to run application processes in a container, which are like virtual machines, only more portable, more resource-friendly, and more dependent on the host operating system. For a detailed introduction to the different components of a Docker container, check out The Docker Ecosystem: An Introduction to Common Components.

There are two methods for installing Docker on Ubuntu 16.04. One method involves installing it on an existing installation of the operating system. The other involves spinning up a server with a tool called Docker Machine that auto-installs Docker on it.

In this tutorial, you’ll learn how to install and use it on an existing installation of Ubuntu 16.04.

Prerequisites

To follow this tutorial, you will need the following:

Note: Docker requires a 64-bit version of Ubuntu as well as a kernel version equal to or greater than 3.10. The default 64-bit Ubuntu 16.04 server meets these requirements.

All the commands in this tutorial should be run as a non-root user. If root access is required for the command, it will be preceded by sudoInitial Setup Guide for Ubuntu 16.04 explains how to add users and give them sudo access.

Step 1 — Installing Docker

The Docker installation package available in the official Ubuntu 16.04 repository may not be the latest version. To get the latest and greatest version, install Docker from the official Docker repository. This section shows you how to do just that.

First, add the GPG key for the official Docker repository to the system:

Add the Docker repository to APT sources:

Next, update the package database with the Docker packages from the newly added repo:

  • sudo apt-get update

Make sure you are about to install from the Docker repo instead of the default Ubuntu 16.04 repo:

  • apt-cache policy docker-ce

You should see output similar to the follow:

Output of apt-cache policy docker-ce
docker-ce:
  Installed: (none)
  Candidate: 17.03.1~ce-0~ubuntu-xenial
  Version table:
     17.03.1~ce-0~ubuntu-xenial 500
        500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages
     17.03.0~ce-0~ubuntu-xenial 500
        500 https://download.docker.com/linux/ubuntu xenial/stable amd64 Packages

Notice that docker-ce is not installed, but the candidate for installation is from the Docker repository for Ubuntu 16.04. The docker-ce version number might be different.

Finally, install Docker:

  • sudo apt-get install -y docker-ce

Docker should now be installed, the daemon started, and the process enabled to start on boot. Check that it’s running:

  • sudo systemctl status docker

The output should be similar to the following, showing that the service is active and running:

Output
● docker.service - Docker Application Container Engine
   Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2016-05-01 06:53:52 CDT; 1 weeks 3 days ago
     Docs: https://docs.docker.com
 Main PID: 749 (docker)

Installing Docker now gives you not just the Docker service (daemon) but also the docker command line utility, or the Docker client. We’ll explore how to use the docker command later in this tutorial.

Step 2 — Executing the Docker Command Without Sudo (Optional)

By default, running the docker command requires root privileges — that is, you have to prefix the command with sudo. It can also be run by a user in the docker group, which is automatically created during the installation of Docker. If you attempt to run the docker command without prefixing it with sudoor without being in the docker group, you’ll get an output like this:

Output
docker: Cannot connect to the Docker daemon. Is the docker daemon running on this host?.
See 'docker run --help'.

If you want to avoid typing sudo whenever you run the docker command, add your username to the docker group:

  • sudo usermod -aG docker ${USER}

To apply the new group membership, you can log out of the server and back in, or you can type the following:

  • su – ${USER}

You will be prompted to enter your user’s password to continue. Afterwards, you can confirm that your user is now added to the docker group by typing:

  • id -nG
Output
sammy sudo docker

If you need to add a user to the docker group that you’re not logged in as, declare that username explicitly using:

  • sudo usermod -aG docker username

The rest of this article assumes you are running the docker command as a user in the docker user group. If you choose not to, please prepend the commands with sudo.

Step 3 — Using the Docker Command

With Docker installed and working, now’s the time to become familiar with the command line utility. Using docker consists of passing it a chain of options and commands followed by arguments. The syntax takes this form:

  • docker [option] [command] [arguments]

To view all available subcommands, type:

  • docker

As of Docker 1.11.1, the complete list of available subcommands includes:

Output

    attach    Attach to a running container
    build     Build an image from a Dockerfile
    commit    Create a new image from a container's changes
    cp        Copy files/folders between a container and the local filesystem
    create    Create a new container
    diff      Inspect changes on a container's filesystem
    events    Get real time events from the server
    exec      Run a command in a running container
    export    Export a container's filesystem as a tar archive
    history   Show the history of an image
    images    List images
    import    Import the contents from a tarball to create a filesystem image
    info      Display system-wide information
    inspect   Return low-level information on a container or image
    kill      Kill a running container
    load      Load an image from a tar archive or STDIN
    login     Log in to a Docker registry
    logout    Log out from a Docker registry
    logs      Fetch the logs of a container
    network   Manage Docker networks
    pause     Pause all processes within a container
    port      List port mappings or a specific mapping for the CONTAINER
    ps        List containers
    pull      Pull an image or a repository from a registry
    push      Push an image or a repository to a registry
    rename    Rename a container
    restart   Restart a container
    rm        Remove one or more containers
    rmi       Remove one or more images
    run       Run a command in a new container
    save      Save one or more images to a tar archive
    search    Search the Docker Hub for images
    start     Start one or more stopped containers
    stats     Display a live stream of container(s) resource usage statistics
    stop      Stop a running container
    tag       Tag an image into a repository
    top       Display the running processes of a container
    unpause   Unpause all processes within a container
    update    Update configuration of one or more containers
    version   Show the Docker version information
    volume    Manage Docker volumes
    wait      Block until a container stops, then print its exit code

To view the switches available to a specific command, type:

  • docker docker-subcommand –help

To view system-wide information about Docker, use:

  • docker info

Step 4 — Working with Docker Images

Docker containers are run from Docker images. By default, it pulls these images from Docker Hub, a Docker registry managed by Docker, the company behind the Docker project. Anybody can build and host their Docker images on Docker Hub, so most applications and Linux distributions you’ll need to run Docker containers have images that are hosted on Docker Hub.

To check whether you can access and download images from Docker Hub, type:

  • docker run hello-world

The output, which should include the following, should indicate that Docker in working correctly:

Output
Hello from Docker.
This message shows that your installation appears to be working correctly.
...

You can search for images available on Docker Hub by using the docker command with the searchsubcommand. For example, to search for the Ubuntu image, type:

  • docker search ubuntu

The script will crawl Docker Hub and return a listing of all images whose name match the search string. In this case, the output will be similar to this:

Output

NAME                              DESCRIPTION                                     STARS     OFFICIAL   AUTOMATED
ubuntu                            Ubuntu is a Debian-based Linux operating s...   3808      [OK]       
ubuntu-upstart                    Upstart is an event-based replacement for ...   61        [OK]       
torusware/speedus-ubuntu          Always updated official Ubuntu docker imag...   25                   [OK]
rastasheep/ubuntu-sshd            Dockerized SSH service, built on top of of...   24                   [OK]
ubuntu-debootstrap                debootstrap --variant=minbase --components...   23        [OK]       
nickistre/ubuntu-lamp             LAMP server on Ubuntu                           6                    [OK]
nickistre/ubuntu-lamp-wordpress   LAMP on Ubuntu with wp-cli installed            5                    [OK]
nuagebec/ubuntu                   Simple always updated Ubuntu docker images...   4                    [OK]
nimmis/ubuntu                     This is a docker images different LTS vers...   4                    [OK]
maxexcloo/ubuntu                  Docker base image built on Ubuntu with Sup...   2                    [OK]
admiringworm/ubuntu               Base ubuntu images based on the official u...   1                    [OK]

...

In the OFFICIAL column, OK indicates an image built and supported by the company behind the project. Once you’ve identified the image that you would like to use, you can download it to your computer using the pull subcommand, like so:

  • docker pull ubuntu

After an image has been downloaded, you may then run a container using the downloaded image with the run subcommand. If an image has not been downloaded when docker is executed with the runsubcommand, the Docker client will first download the image, then run a container using it:

  • docker run ubuntu

To see the images that have been downloaded to your computer, type:

  • docker images

The output should look similar to the following:

Output
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              c5f1cf30c96b        7 days ago          120.8 MB
hello-world         latest              94df4f0ce8a4        2 weeks ago         967 B

As you’ll see later in this tutorial, images that you use to run containers can be modified and used to generate new images, which may then be uploaded (pushed is the technical term) to Docker Hub or other Docker registries.

Step 5 — Running a Docker Container

The hello-world container you ran in the previous is an example of a container that runs and exits, after emitting a test message. Containers, however, can be much more useful than that, and they can be interactive. After all, they are similar to virtual machines, only more resource-friendly.

As an example, let’s run a container using the latest image of Ubuntu. The combination of the -i and -tswitches gives you interactive shell access into the container:

  • docker run -it ubuntu

Your command prompt should change to reflect the fact that you’re now working inside the container and should take this form:

Output
root@d9b100f2f636:/#

Important: Note the container id in the command prompt. In the above example, it is d9b100f2f636.

Now you may run any command inside the container. For example, let’s update the package database inside the container. No need to prefix any command with sudo, because you’re operating inside the container with root privileges:

  • apt-get update

Then install any application in it. Let’s install NodeJS, for example.

  • apt-get install -y nodejs

Step 6 — Committing Changes in a Container to a Docker Image

When you start up a Docker image, you can create, modify, and delete files just like you can with a virtual machine. The changes that you make will only apply to that container. You can start and stop it, but once you destroy it with the docker rm command, the changes will be lost for good.

This section shows you how to save the state of a container as a new Docker image.

After installing nodejs inside the Ubuntu container, you now have a container running off an image, but the container is different from the image you used to create it.

To save the state of the container as a new image, first exit from it:

  • exit

Then commit the changes to a new Docker image instance using the following command. The -m switch is for the commit message that helps you and others know what changes you made, while -a is used to specify the author. The container ID is the one you noted earlier in the tutorial when you started the interactive docker session. Unless you created additional repositories on Docker Hub, the repository is usually your Docker Hub username:

  • docker commit -m “What did you do to the image” -a “Author Name” container-id repository/new_image_name

For example:

  • docker commit -m “added node.js” -a “Sunday Ogwu-Chinuwa” d9b100f2f636 finid/ubuntu-nodejs

Note: When you commit an image, the new image is saved locally, that is, on your computer. Later in this tutorial, you’ll learn how to push an image to a Docker registry like Docker Hub so that it may be assessed and used by you and others.

After that operation has completed, listing the Docker images now on your computer should show the new image, as well as the old one that it was derived from:

  • docker images

The output should be similar to this:

Output
finid/ubuntu-nodejs       latest              62359544c9ba        50 seconds ago      206.6 MB
ubuntu              latest              c5f1cf30c96b        7 days ago          120.8 MB
hello-world         latest              94df4f0ce8a4        2 weeks ago         967 B

In the above example, ubuntu-nodejs is the new image, which was derived from the existing ubuntu image from Docker Hub. The size difference reflects the changes that were made. And in this example, the change was that NodeJS was installed. So next time you need to run a container using Ubuntu with NodeJS pre-installed, you can just use the new image. Images may also be built from what’s called a Dockerfile. But that’s a very involved process that’s well outside the scope of this article.

Step 7 — Listing Docker Containers

After using Docker for a while, you’ll have many active (running) and inactive containers on your computer. To view the active ones, use:

  • docker ps

You will see output similar to the following:

Output
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
f7c79cc556dd        ubuntu              "/bin/bash"         3 hours ago         Up 3 hours                              silly_spence

To view all containers — active and inactive, pass it the -a switch:

  • docker ps -a

To view the latest container you created, pass it the -l switch:

  • docker ps -l

Stopping a running or active container is as simple as typing:

  • docker stop container-id

The container-id can be found in the output from the docker ps command.

Step 8 — Pushing Docker Images to a Docker Repository

The next logical step after creating a new image from an existing image is to share it with a select few of your friends, the whole world on Docker Hub, or other Docker registry that you have access to. To push an image to Docker Hub or any other Docker registry, you must have an account there.

This section shows you how to push a Docker image to Docker Hub. To learn how to create your own private Docker registry, check out How To Set Up a Private Docker Registry on Ubuntu 14.04.

To create an account on Docker Hub, register at Docker Hub. Afterwards, to push your image, first log into Docker Hub. You’ll be prompted to authenticate:

  • docker login -u docker-registry-username

If you specified the correct password, authentication should succeed. Then you may push your own image using:

  • docker push docker-registry-username/docker-image-name

It will take sometime to complete, and when completed, the output will similar to the following:

Output
The push refers to a repository [docker.io/finid/ubuntu-nodejs]
e3fbbfb44187: Pushed
5f70bf18a086: Pushed
a3b5c80a4eba: Pushed
7f18b442972b: Pushed
3ce512daaf78: Pushed
7aae4540b42d: Pushed

...

After pushing an image to a registry, it should be listed on your account’s dashboard, like that show in the image below.

New Docker image listing on Docker Hub

If a push attempt results in an error of this sort, then you likely did not log in:

Output
The push refers to a repository [docker.io/finid/ubuntu-nodejs]
e3fbbfb44187: Preparing
5f70bf18a086: Preparing
a3b5c80a4eba: Preparing
7f18b442972b: Preparing
3ce512daaf78: Preparing
7aae4540b42d: Waiting
unauthorized: authentication required

Log in, then repeat the push attempt.

Conclusion

There’s a whole lot more to Docker than has been given in this article, but this should be enough to getting you started working with it on Ubuntu 16.04. Like most open source projects, Docker is built from a fast-developing codebase, so make a habit of visiting the project’s blog page for the latest information.

Also check out the other Docker tutorials in the DO Community.

 

Cited from: https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-16-04

MySQL Commands

shell> mysql -h host -u user -p
Enter password: ********

mysql> QUIT
Bye
##########################################################################
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| VERSION()    | CURRENT_DATE |
+--------------+--------------+
| 5.5.0-m2-log | 2009-05-04   |
+--------------+--------------+
1 row in set (0.01 sec)
mysql>

mysql> SHOW DATABASES;
+----------+
| Database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+

mysql> USE test
Database changed

mysql> GRANT ALL ON menagerie.* TO 'your_mysql_name'@'your_client_host';

mysql> CREATE DATABASE menagerie;
mysql> USE menagerie
Database changed
shell> mysql -h host -u user -p menagerie
Enter password: ********
mysql> SHOW TABLES;
Empty set (0.00 sec)
##########################################################################

mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20),
    -> species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);

mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet                 |
+---------------------+
##########################################################################
name	owner	species	sex	birth	death
Fluffy	Harold	cat	f	1993-02-04
Claws	Gwen	cat	m	1994-03-17
Buffy	Harold	dog	f	1989-05-13
Fang	Benny	dog	m	1990-08-27
Bowser	Diane	dog	m	1979-08-31	1995-07-29
Chirpy	Gwen	bird	f	1998-09-11
Whistler	Gwen	bird	 	1997-12-09
Slim	Benny	snake	m	1996-04-29	 

mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
mysql> INSERT INTO pet
    -> VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
mysql> SELECT * FROM pet;
+----------+--------+---------+------+------------+------------+
| name     | owner  | species | sex  | birth      | death      |
+----------+--------+---------+------+------------+------------+
| Fluffy   | Harold | cat     | f    | 1993-02-04 | NULL       |
| Claws    | Gwen   | cat     | m    | 1994-03-17 | NULL       |
| Buffy    | Harold | dog     | f    | 1989-05-13 | NULL       |
| Fang     | Benny  | dog     | m    | 1990-08-27 | NULL       |
| Bowser   | Diane  | dog     | m    | 1979-08-31 | 1995-07-29 |
| Chirpy   | Gwen   | bird    | f    | 1998-09-11 | NULL       |
| Whistler | Gwen   | bird    | NULL | 1997-12-09 | NULL       |
| Slim     | Benny  | snake   | m    | 1996-04-29 | NULL       |
| Puffball | Diane  | hamster | f    | 1999-03-30 | NULL       |
+----------+--------+---------+------+------------+------------+
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE '/path/pet.txt' INTO TABLE pet;
mysql> UPDATE pet SET birth = '1989-08-31' WHERE name = 'Bowser';
##########################################################################
mysql> SELECT * FROM pet WHERE name = 'Bowser';
+--------+-------+---------+------+------------+------------+
| name   | owner | species | sex  | birth      | death      |
+--------+-------+---------+------+------------+------------+
| Bowser | Diane | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+-------+---------+------+------------+------------+
mysql> SELECT * FROM pet WHERE birth >= '1998-1-1';
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Chirpy   | Gwen  | bird    | f    | 1998-09-11 | NULL  |
| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
+----------+-------+---------+------+------------+-------+
mysql> SELECT * FROM pet WHERE species = 'dog' AND sex = 'f';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
mysql> SELECT * FROM pet WHERE (species = 'cat' AND sex = 'm')
    -> OR (species = 'dog' AND sex = 'f');
##########################################################################

mysql> SELECT name, birth FROM pet ORDER BY birth;
+----------+------------+
| name     | birth      |
+----------+------------+
| Buffy    | 1989-05-13 |
| Bowser   | 1989-08-31 |
| Fang     | 1990-08-27 |
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Slim     | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy   | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
mysql> SELECT name, species, birth FROM pet
    -> ORDER BY species, birth DESC;
+----------+---------+------------+
| name     | species | birth      |
+----------+---------+------------+
| Chirpy   | bird    | 1998-09-11 |
| Whistler | bird    | 1997-12-09 |
| Claws    | cat     | 1994-03-17 |
| Fluffy   | cat     | 1993-02-04 |
| Fang     | dog     | 1990-08-27 |
| Bowser   | dog     | 1989-08-31 |
| Buffy    | dog     | 1989-05-13 |
| Puffball | hamster | 1999-03-30 |
| Slim     | snake   | 1996-04-29 |
+----------+---------+------------+
##########################################################################
mysql> SELECT name, birth, CURDATE(),
    -> TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
    -> FROM pet ORDER BY name;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
+----------+------------+------------+------+
##########################################################################
mysql> SELECT name, birth, CURDATE(),
    -> TIMESTAMPDIFF(YEAR,birth,CURDATE()) AS age
    -> FROM pet ORDER BY age;
+----------+------------+------------+------+
| name     | birth      | CURDATE()  | age  |
+----------+------------+------------+------+
| Chirpy   | 1998-09-11 | 2003-08-19 |    4 |
| Puffball | 1999-03-30 | 2003-08-19 |    4 |
| Whistler | 1997-12-09 | 2003-08-19 |    5 |
| Slim     | 1996-04-29 | 2003-08-19 |    7 |
| Claws    | 1994-03-17 | 2003-08-19 |    9 |
| Fluffy   | 1993-02-04 | 2003-08-19 |   10 |
| Fang     | 1990-08-27 | 2003-08-19 |   12 |
| Bowser   | 1989-08-31 | 2003-08-19 |   13 |
| Buffy    | 1989-05-13 | 2003-08-19 |   14 |
+----------+------------+------------+------+
mysql> SELECT name, birth, death,
    -> TIMESTAMPDIFF(YEAR,birth,death) AS age
    -> FROM pet WHERE death IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name   | birth      | death      | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 |    5 |
+--------+------------+------------+------+
mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MONTH(DATE_ADD(CURDATE(),INTERVAL 1 MONTH));
mysql> SELECT name, birth FROM pet
    -> WHERE MONTH(birth) = MOD(MONTH(CURDATE()), 12) + 1;
##########################################################################
mysql> SELECT * FROM pet WHERE name LIKE 'b%';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
mysql> SELECT * FROM pet WHERE name REGEXP '^b';
+--------+--------+---------+------+------------+------------+
| name   | owner  | species | sex  | birth      | death      |
+--------+--------+---------+------+------------+------------+
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL       |
| Bowser | Diane  | dog     | m    | 1989-08-31 | 1995-07-29 |
+--------+--------+---------+------+------------+------------+
mysql> SELECT * FROM pet WHERE name REGEXP 'fy$';
+--------+--------+---------+------+------------+-------+
| name   | owner  | species | sex  | birth      | death |
+--------+--------+---------+------+------------+-------+
| Fluffy | Harold | cat     | f    | 1993-02-04 | NULL  |
| Buffy  | Harold | dog     | f    | 1989-05-13 | NULL  |
+--------+--------+---------+------+------------+-------+
mysql> SELECT * FROM pet WHERE name REGEXP '^.....$';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
mysql> SELECT * FROM pet WHERE name REGEXP '^.{5}$';
+-------+--------+---------+------+------------+-------+
| name  | owner  | species | sex  | birth      | death |
+-------+--------+---------+------+------------+-------+
| Claws | Gwen   | cat     | m    | 1994-03-17 | NULL  |
| Buffy | Harold | dog     | f    | 1989-05-13 | NULL  |
+-------+--------+---------+------+------------+-------+
##########################################################################
mysql> SELECT owner, COUNT(*) FROM pet GROUP BY owner;
mysql> SELECT species, sex, COUNT(*) FROM pet GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| bird    | NULL |        1 |
| bird    | f    |        1 |
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
| hamster | f    |        1 |
| snake   | m    |        1 |
+---------+------+----------+
mysql> SELECT species, sex, COUNT(*) FROM pet
    -> WHERE species = 'dog' OR species = 'cat'
    -> GROUP BY species, sex;
+---------+------+----------+
| species | sex  | COUNT(*) |
+---------+------+----------+
| cat     | f    |        1 |
| cat     | m    |        1 |
| dog     | f    |        1 |
| dog     | m    |        2 |
+---------+------+----------+
##########################################################################
##Using More Than one Table
mysql> CREATE TABLE event (name VARCHAR(20), date DATE,
    -> type VARCHAR(15), remark VARCHAR(255));
name	date	type	remark
Fluffy	1995-05-15	litter	4 kittens, 3 female, 1 male
Buffy	1993-06-23	litter	5 puppies, 2 female, 3 male
Buffy	1994-06-19	litter	3 puppies, 3 female
Chirpy	1999-03-21	vet	needed beak straightened
Slim	1997-08-03	vet	broken rib
Bowser	1991-10-12	kennel
Fang	1991-10-12	kennel
Fang	1998-08-28	birthday	Gave him a new chew toy
Claws	1998-03-17	birthday	Gave him a new flea collar
Whistler	1998-12-09	birthday	First birthday
mysql> LOAD DATA LOCAL INFILE 'event.txt' INTO TABLE event;
##########################################################################
mysql> SELECT pet.name,
    -> TIMESTAMPDIFF(YEAR,birth,date) AS age,
    -> remark
    -> FROM pet INNER JOIN event
    ->   ON pet.name = event.name
    -> WHERE event.type = 'litter';
+--------+------+-----------------------------+
| name   | age  | remark                      |
+--------+------+-----------------------------+
| Fluffy |    2 | 4 kittens, 3 female, 1 male |
| Buffy  |    4 | 5 puppies, 2 female, 3 male |
| Buffy  |    5 | 3 puppies, 3 female         |
+--------+------+-----------------------------+
mysql> SELECT p1.name, p1.sex, p2.name, p2.sex, p1.species
    -> FROM pet AS p1 INNER JOIN pet AS p2
    ->   ON p1.species = p2.species AND p1.sex = 'f' AND p2.sex = 'm';
+--------+------+--------+------+---------+
| name   | sex  | name   | sex  | species |
+--------+------+--------+------+---------+
| Fluffy | f    | Claws  | m    | cat     |
| Buffy  | f    | Fang   | m    | dog     |
| Buffy  | f    | Bowser | m    | dog     |
+--------+------+--------+------+---------+
##########################################################################
CREATE TABLE shop (
    article INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
    dealer  CHAR(20)                 DEFAULT ''     NOT NULL,
    price   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL,
    PRIMARY KEY(article, dealer));
INSERT INTO shop VALUES
    (1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),
    (3,'C',1.69),(3,'D',1.25),(4,'D',19.95);
SELECT * FROM shop;

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | A      |  3.45 |
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | B      |  1.45 |
|    0003 | C      |  1.69 |
|    0003 | D      |  1.25 |
|    0004 | D      | 19.95 |
+---------+--------+-------+
SELECT article, dealer, price
FROM   shop
WHERE  price=(SELECT MAX(price) FROM shop);

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0004 | D      | 19.95 |
+---------+--------+-------+
SELECT article, dealer, price
FROM   shop s1
WHERE  price=(SELECT MAX(s2.price)
              FROM shop s2
              WHERE s1.article = s2.article);

+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
|    0001 | B      |  3.99 |
|    0002 | A      | 10.99 |
|    0003 | C      |  1.69 |
|    0004 | D      | 19.95 |
+---------+--------+-------+

##########################################################################

##########################################################################

##########################################################################

##########################################################################