Web-Based Guacamole tool

Guacamole website: https://guacamole.incubator.apache.org/

Create database for Guacamole: (DB name is guacamole_db)

$ mysql -u root -p

mysql> create database guacamole_db;
mysql> grant all privileges on guacamole_db.* to guacamole_user@localhost identified by 'secure password';
mysql> flush  privileges;

Initializing the MySQL database

$ docker run --rm guacamole/guacamole /opt/guacamole/bin/initdb.sh --mysql > initdb.sql

$ mysql -u guacamole_user -p guacamole_db < initdb.sql

Create my-guacd docker container

$ docker run --name my-guacd -d guacamole/guacd

Create my-guacamole docker container

docker run --name my-guacamole \
  --link my-guacd:guacd \
  -d -p 8080:8080 guacamole/guacamole


http://<server ip>:8080/guacamole/


$ docker logs my-guacamole

Behind apache proxy:

<Location /guacamole/>
    Order allow,deny
    Allow from all
    ProxyPass http://HOSTNAME:8080/guacamole/ flushpackets=on
    ProxyPassReverse http://HOSTNAME:8080/guacamole/

<Location /guacamole/websocket-tunnel>
    Order allow,deny
    Allow from all
    ProxyPass ws://HOSTNAME:8080/guacamole/websocket-tunnel
    ProxyPassReverse ws://HOSTNAME:8080/guacamole/websocket-tunnel

Using AWK

//print the first column
awk -F":" ' { print $1 } ' /etc/passwd  
// print 1st column and last column
awk -F":" ' { print $1, $NF} ' /etc/passwd 
//print 1st column of 1st ten records
awk -F":" ' NR==1,NR==10 { print $1 } ' /etc/passwd
//print 1st column length of 1st ten records 
awk -F":" ' NR==1,NR==10 { print length($1) } ' /etc/passwd 
// using printf to format output
awk -F":" ' NR==1,NR==10 { printf "%-8s %3d\n" , $1,$3 } ' /etc/passwd 
// add header and footer for output
awk -F":" '
BEGIN { printf "%-8s %-3s\n" , "User", "UID" }
NR==1,NR==10 { printf "%-8s %3d\n" , $1,$3 } 
END { print "============== END ============="} ' /etc/passwd
// add output filed separator between columns
awk -F":" ' { OFS="|";print $1, $NF } ' /etc/passwd
// condition
awk -F":" ' /^root/ { print $1, $NF } ' /etc/passwd
awk -F":" ' { if($1 ~ /root/) { print $1, $NF } }' /etc/passwd


Linux Job Interview Questions

  1. How can you see which kernel version a system is currently running?
uname -a  // Show hostname, current version, current release

uname -v  //Show current version

uname -r  // Show current release

2.How can you check a system’s current IP address?

ip addr show
ip addr show eth0

3. How do you check for free disk space?

df -ah

4. How dow you manage services on a system?

service <service name> status
systemctl status <service name>

5. How would you check the size of a directory’s contents on disk?

du -sh <directory name>

6. How would you check for open ports on a Linux machine?

sudo netstat  -tulpn

7. How do you check CPU usage for a process?

ps aux |grep <process name> 

8. Dealing with Mounts

ls /mnt
mount <device/network drive> <mount point>

9. How do you look up something you don’t know?

man <command>
<command> --h


Open range ports via ufw or iptables


ufw allow from any to any port 4000:4020 proto tcp

For iptables

iptables -A tableName -p tcp  --match multiport --dports port1,port2 -j ACCEPT
iptables -A tableName -p udp  --match multiport --dports port1,port2 -j DROP
iptables -A tableName -p protocol  --match multiport --dports portRange1:PortRange2 -j ACCEPT
iptables -A tableName -p tcp  --match multiport --sports port1,port2 -j ACCEPT
iptables -A tableName -p udp  --match multiport --sports port1,port2 -j DROP
iptables -A tableName -p protocol  --match multiport --sports portRange1:PortRange2 -j ACCEPT

Correct way to move kvm vm

I have a problem to do live migration between two host computers via virt manager. It is a permission issue but I don’t have time to fig it out. It is not a big deal. It is ok to move KVM vms offline.

  1. stop VM from gui or cli or guest console
  2. dump guest configuration as xml
    virsh dumpxml VMNAME > domxml.xml
  3. copy the guest images to another server with same path
  4. define a VM from the dump xml file
    virsh define domxml.xml
  5. Check the configuration and start VM on new host. Usually need to check the network configuration, CPU, and memory.

source: http://serverfault.com/questions/434064/correct-way-to-move-kvm-vm

Using docker and zfs to create limited size mysql database

Idea: Docker is run mysql server. Mysql data is stored on zfs volume and set the quota by zfs utility. Assume zpool name is zpool-mysql and mount point is /mysqldata

  1. Create volume for mysql data (test_quota)

    sudo zfs create -o quota=1.4gb -o mountpoint=/mysqldata/test_quota zpool-mysql/test_quota
  2. Create mysql instance. Port forwarding is from host 8306 to guest 3306. User can access database using host port 8306.

    docker run --name test_quota-db -e MYSQL_ROOT_PASSWORD=rootpassword -e MYSQL_DATABASE=my_test_quota -e MYSQL_USER=dbusername -e MYSQL_PASSWORD=dbuserpassword -v /mysqldata/test_quota:/var/lib/mysql -d  -p 8306:3306 mysql:latest
  3. Create systemd service for the container (test_quota-db.service)

    Description=Mysql with quota setting
    ExecStart=/usr/bin/docker start -a test_quota-db
    ExecStop=/usr/bin/docker stop -t 2 test_quota-db


    sudo systemctl enable test_quota-db.service
  4. Using phpMyAdmin to manage database

    docker run --name test_quota-phpmyadmin --link test_quota-db:db -e MYSQL_ROOT_PASSWORD=rootpassword -d -p 8080:80 phpmyadmin/phpmyadmin:latest


    Description=phpMyAdmin for test_quota-db service
    ExecStart=/usr/bin/docker start -a test_quota-phpmyadmin
    ExecStop=/usr/bin/docker stop -t 2 test_quota-phpmyadmin


    sudo systemctl enable test_quota-phpmyadmin.service

KVM access guest from outside host on CentOS

For default virbr0, it provides a way to help guest to access host (VM<–>host). But the guest cannot be accessed from outside host. But we can use the following commands to enable it temporally.

# iptables -D  FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
# iptables -D  FORWARD -i virbr0 -j REJECT --reject-with icmp-port-unreachable

The best way is to create another bridge for guest.

  1. create new bridge xml file (routeNetwork.xml)

      <bridge name="virbr100" />
      <forward mode="route" />
      <ip address="" netmask="" />
  2. create new bridge
    # virsh net-create routeNetwork.xml
  3. edit the bridge to enable dhcp (I think if we define DHCP at the first step, no need this one. If we don’t do this step, the persistent state is no. Not sure what the impact is.)
    # virsh net-edit routenetwork
      <forward mode='route'/>
      <bridge name='virbr100' stp='on' delay='0'/>
      <mac address='52:54:00:cc:3b:aa'/>
      <ip address='' netmask=''>
          <range start='' end=''/>
  4. Set the bridge autostart
    # virsh net-autostart routenetwork
  5. Check virtual networks
    # virsh net-list
     Name                 State      Autostart     Persistent
     default              active     yes           yes
     routenetwork         active     yes           yes
  6. add masquerade to firewalld
    # firewall-cmd --permanent --add-masquerade
  7. change guest network type
    # virsh --connect qemu:///system
    virsh # edit <VM's name>
    <interface type='bridge'>
      <mac address='52:54:00:ea:98:1a'/>
      <source bridge='virbr100'/>
      <model type='e1000'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
  8. shutdown and start the guest again
  9. add route on your router
    # sudo route -n add <host ip>

    Now the guest can access from your network via it ip 10.10.120.x.

    Other virsh commands used in managing virtual networks are:

    • virsh net-list — list virtual networks
    • virsh net-autostart [network name] — Autostart a network specified as [network name]
    • virsh net-create [XML file] — Generates and starts a new network using a preexisting XML file
    • virsh net-define [XML file] — Generates a new network from a preexisting XML file without starting it
    • virsh net-destroy [network name] — Destroy a network specified as [network name]
    • virsh net-name [network UUID] — Convert a specified [network UUID] to a network name
    • virsh net-uuid [network name — Convert a specified [network name] to a network UUID
    • virsh net-start [name of an inactive network] — Starts a previously undefined inactive network
    • virsh net-undefine [name of an inactive network] — Undefine an inactive network
    • virsh net-dumpxml [network name] — Dump network as xml file

How to edit KVM VM profile which is created by virt-manager and add port-forwarding function?

Virt-manager hides some functions such as port-forwarding. We can edit the VM profile form terminal.

# virsh --connect qemu:///system

List all VMs in virsh envrionment

virsh # list --all

Edit VM’s profile

virsh # edit <VM's name>

Add qemu namespace

<domain type='kvm'>
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

Change network type from network to user

   <interface type='network'>
      <mac address='xx:xx:xx:xx:xx:xx'/>
      <model type='e1000'/>
      <source network='default'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
  <interface type='user'>
    <mac address='xx:xx:xx:xx:xx:xx'/>
    <model type='e1000'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>

Add port-forwarding arguments before tag </domain>

    <qemu:arg value='-redir'/>
    <qemu:arg value='tcp:2001::3389'/>
    <qemu:arg value='-redir'/>
    <qemu:arg value='tcp:2002::80'/>



Ubuntu 16.04 Winbind and Active Directory

Official SSSD and Active Directory guide doesn’t work. It is hard to find what’s wrong. Using Winbind works well.


sudo apt install winbind samba
sudo apt install cups-common python-crypto-dbg python-crypto-doc bind9 bind9utils ctdb ldb-tools ntp smbldap-tools heimdal-clients libnss-winbind libpam-winbind


sudo vi /etc/samba/smb.conf

## Browsing/Identification ###

# Change this to the workgroup/NT-domain name your Samba server will part of
#   workgroup = GROUP

# server string is the equivalent of the NT Description field
  server string = %h server (Samba, Ubuntu)

        security = ads
        realm = MYDOMAIN.COM
# If the system doesn't find the domain controller automatically, you may need the following line
#        password server =
# note that workgroup is the 'short' domain name
        workgroup = MYDOMAIN
#       winbind separator = +
        idmap uid = 10000-20000
        idmap gid = 10000-20000
        winbind enum users = yes
        winbind enum groups = yes
        template homedir = /home/%D/%U
        template shell = /bin/bash
        client use spnego = yes
        client ntlmv2 auth = yes
        encrypt passwords = yes
        winbind use default domain = yes
        restrict anonymous = 2

Restart services:

sudo service winbind stop
sudo service samba-ad-dc restart
sudo service winbind start

Join the AD (see “net ads help”):

sudo kinit Admin@MYDOMAIN.COM
# check klist
sudo klist
# join (ignore the dns error messages)
sudo net ads join -k

sudo net ads join -U Admin@MYDOMAIN.COM

Setup Authentication

sudo vi /etc/nsswitch.conf


passwd:         compat winbind
group:          compat winbind
shadow:         compat

Restart Winbind

sudo service winbind restart

PAM Configuration

sudo pam-auth-update

Create Home directory

sudo mkdir /home/MYDOMAIN

Add sudo users

sudo vi /etc/sudoers.d/MYDOMAIN


# replace adgroup as real domain group name
%adgroup        ALL=(ALL) NOPASSWD: ALL


wbinfo -u
wbinfo -g

Login as a domain user and enjoy…