CentOS 7. Did you know…?

This post is just a reminder of some things that you may have not noticed when working with CentOS 7. I’ll be updating it from time to time.

  • Remember those times when you had to use nohup with a command so it could run on the background even if you closed the shell from where it was launched? That’s no longer needed with CentOS 7, if you have a background job and you close that shell, the process will run! No more nohup needed.
  • You can use yum to install locally rpm files you’ve downloaded so dependencies are installed automatically. We used to use yum localinstall but now you can use yum install right away.

OPENVSWITCH LTS IN CENTOS 6

As some visitors have asked me about installing Open vSwitch on CentOS 6, I’m writing the following post after my first about it almos three years ago. If you find a better way, please let me know so I update the post and remove useless info from the Internet 😉

I’ve found this repository by Alexander Evseev so you may try to use the openvswitch packages (you even have the kmod package) found there. Have a look: http://download.opensuse.org/repositories/home:/aevseev/CentOS6/x86_64/

In any case… I’ll show you what you can do to generate your own RPM packages the old way (no python api supported as it requires Python 2.7 while CentOS 6 uses Python 2.6):

Current LTS version: 2.5.0
Tested on: CentOS 6.8

Let’s start installing some packages:

yum -y install wget openssl-devel gcc make python-devel openssl-devel kernel-devel graphviz kernel-debug-devel autoconf automake rpm-build redhat-rpm-config libtool python-twisted-core python-zope-interface PyQt4 desktop-file-utils libcap-ng-devel groff checkpolicy selinux-policy-devel

Let’s add a new user and switch to that user:

adduser ovs; su - ovs

Let’s prepare the build environment and download the source code:

mkdir -p ~/rpmbuild/SOURCES
wget http://openvswitch.org/releases/openvswitch-2.5.0.tar.gz
cp openvswitch-2.5.0.tar.gz ~/rpmbuild/SOURCES/
tar xfz openvswitch-2.5.0.tar.gz

Now go to the openvswitch directory

cd openvswitch-2.5.0

Let’s modify some lines in the old rhel6 spec file provided by Nicira (copy and paste):

sed -i "s/Requires: logrotate, python >= 2.7/Requires: logrotate/" rhel/openvswitch.spec
sed -i "/$RPM_BUILD_ROOT\/usr\/bin\/ovs-test/d" rhel/openvswitch.spec
sed -i "/$RPM_BUILD_ROOT\/usr\/bin\/ovs-l3ping/d" rhel/openvswitch.spec
sed -i "/\/usr\/bin\/ovs-parse-backtrace/d" rhel/openvswitch.spec
sed -i "/\/usr\/bin\/ovs-pcap/d" rhel/openvswitch.spec
sed -i "/\/usr\/bin\/ovs-tcpundump/d" rhel/openvswitch.spec
sed -i "/\/usr\/bin\/ovs-vlan-test/d" rhel/openvswitch.spec
sed -i "/\/usr\/share\/man\/man8\/ovs-bugtool.8.gz/d" rhel/openvswitch.spec
sed -i "/\/usr\/share\/openvswitch\/bugtool-plugins/d" rhel/openvswitch.spec
sed -i "/\/usr\/share\/openvswitch\/scripts\/ovs-bugtool-*/d" rhel/openvswitch.spec
sed -i "/\/usr\/share\/openvswitch\/python/d" rhel/openvswitch.spec
sed -i "/\/usr\/share\/openvswitch\/scripts\/ovs-bugtool-*/d" rhel/openvswitch.spec
sed -i "/\/usr\/bin\/ovs-dpctl-top/d" rhel/openvswitch.spec
sed -i "/\/usr\/sbin\/ovs-bugtool/d" rhel/openvswitch.spec
echo "/usr/bin/ovs-testcontroller" >> rhel/openvswitch.spec

Finally let’s build the RPM packages… and have a cup of coffee as tests are being run! At least you can tell if it works… 😛

rpmbuild -bb rhel/openvswitch.spec

Once the build is finished, type exit.

exit

CentOS 6 already provides an openvswitch kernel module, so we’ve only compiled the binary tools.

[root@localhost ~]# modinfo openvswitch
filename: /lib/modules/2.6.32-642.3.1.el6.x86_64/kernel/net/openvswitch/openvswitch.ko
license: GPL
description: Open vSwitch switching datapath
srcversion: 00938868C288DBF055E30F3
depends: libcrc32c,vxlan
vermagic: 2.6.32-642.3.1.el6.x86_64 SMP mod_unload modversions

As root, we’ll install the RPM package.

 yum localinstall /home/ovs/rpmbuild/RPMS/x86_64/openvswitch-2.5.0-1.x86_64.rpm -y

Finally, start the openvswitch service and check that it’s running

service openvswitch start
...output...
/etc/openvswitch/conf.db does not exist ... (warning).
Creating empty database /etc/openvswitch/conf.db [ OK ]
Starting ovsdb-server [ OK ]
Configuring Open vSwitch system IDs [ OK ]
Inserting openvswitch module [ OK ]
Starting ovs-vswitchd [ OK ]
Enabling remote OVSDB managers [ OK ]

service openvswitch status
...output...
ovsdb-server is running with pid 3404
ovs-vswitchd is running with pid 3416

If you want the openvswitch service to start at boot time:

chkconfig openvswitch on

Let’s check that the command-line tools are ready:

ovs-vsctl -V
...output...
ovs-vsctl (Open vSwitch) 2.5.0
Compiled Aug 31 2016 19:54:41
DB Schema 7.12.1

Done. I can’t be sure if it will work for you as I haven’t been using Open vSwitch with CentOS 6 for a long time… so any feedback is welcomed!

Cheers!

Installing latest RabbitMQ on CentOS 7

This post is a quick reminder for the future that may help you too.

If you want to install the latest RabbitMQ package for your CentOS 7 you can do it in only three steps:

sudo yum install epel-release -y
sudo curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
sudo yum install rabbitmq-server -y

Then, as always, you can start it and enable the service:

sudo systemctl enable rabbitmq-server
sudo systemctl start rabbitmq-server

Check that the service is running either with:

sudo systemctl is-active rabbitmq-server

or:

sudo systemctl status rabbitmq-server

If serving to remote hosts, a firewalld rule may be useful:

firewall-cmd --add-port=5672/tcp --zone=public --permanent
firewall-cmd --reload

See ya!

Reference: https://www.rabbitmq.com/install-rpm.html

 

Installing CoreOS etcd server on CentOS 7

While I’m preparing a shell script or test some Ansible roles available at Ansible Galaxy so the installation is automatic, here I show you the steps I followed to install by hand the Etcd server on CentOS 7 as quick and fast as possible.

First of all we have to create some directories (/var/lib/etcd and /etc/etcd) and add the etcd user and group

mkdir /var/lib/etcd;mkdir /etc/etcd; groupadd -r etcd; useradd -r -g etcd -d /var/lib/etcd -s /sbin/nologin -c "etcd user" etcd;chown -R etcd:etcd /var/lib/etcd

Now we have to add a systemd service definition for our etcd service

cat << EOT > /usr/lib/systemd/system/etcd.service
[Unit]
Description=etcd service
After=network.target

[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
User=etcd
ExecStart=/usr/bin/etcd
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOT

Warning: The etcd service needs a configuration file, we install a really simple one that should be modified according to your needs, e.g add urls with your server’s IP address or DNS names so your server is not only useful for localhost and secure client requests. Read https://github.com/coreos/etcd for more info.

cat &lt;&lt; EOT &gt; /etc/etcd/etcd.conf
 # [member]
 ETCD_NAME=default
 ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
 #ETCD_SNAPSHOT_COUNTER="10000"
 #ETCD_HEARTBEAT_INTERVAL="100"
 #ETCD_ELECTION_TIMEOUT="1000"
 #ETCD_LISTEN_PEER_URLS="http://localhost:2380,http://localhost:7001"
 ETCD_LISTEN_CLIENT_URLS="http://localhost:2379"
 ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379"
 #ETCD_MAX_SNAPSHOTS="5"
 #ETCD_MAX_WALS="5"
 #ETCD_CORS=""
 #
 #[cluster]
 #ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380,http://localhost:7001"
 # if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
 #ETCD_INITIAL_CLUSTER="default=http://localhost:2380,default=http://localhost:7001"
 #ETCD_INITIAL_CLUSTER_STATE="new"
 #ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
 #ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379,http://localhost:4001"
 #ETCD_DISCOVERY=""
 #ETCD_DISCOVERY_SRV=""
 #ETCD_DISCOVERY_FALLBACK="proxy"
 #ETCD_DISCOVERY_PROXY=""
 #
 #[proxy]
 #ETCD_PROXY="off"
 #
 #[security]
 #ETCD_CA_FILE=""
 #ETCD_CERT_FILE=""
 #ETCD_KEY_FILE=""
 #ETCD_PEER_CA_FILE=""
 #ETCD_PEER_CERT_FILE=""
 #ETCD_PEER_KEY_FILE=""
 EOT

Time to download and install etcd binaries for Linux x86_64, the following commands should be good for any Linux distro. It downloads the latest stable version available, creates a directory for any downloaded version and changes the symbolinc link accordingly. It runs etcd with the version argument to check that the binary works fine.

ETCD_VERSION=`curl -s -L https://github.com/coreos/etcd/releases/latest | grep linux-amd64\.tar\.gz | grep href | cut -f 6 -d '/' | sort -u`; ETCD_DIR=/opt/etcd-$ETCD_VERSION; mkdir $ETCD_DIR;curl -L https://github.com/coreos/etcd/releases/download/$ETCD_VERSION/etcd-$ETCD_VERSION-linux-amd64.tar.gz | tar xz --strip-components=1 -C $ETCD_DIR; ln -sf $ETCD_DIR/etcd /usr/bin/etcd && ln -sf $ETCD_DIR/etcdctl /usr/bin/etcdctl; etcd --version

We can enable and start the etcd server with:

systemctl enable etcd; systemctl start etcd

Check etcd service status

systemctl status etcd

● etcd.service – etcd service
Loaded: loaded (/usr/lib/systemd/system/etcd.service; enabled; vendor preset: disabled)
Active: active (running) since lun 2016-08-01 10:05:51 UTC; 2s ago
Main PID: 31051 (etcd)
CGroup: /system.slice/etcd.service
└─31051 /usr/bin/etcd

ago 01 10:05:51 localhost.localdomain etcd[31051]: ready to serve client requests
ago 01 10:05:51 localhost.localdomain etcd[31051]: serving insecure client requests on localhost:2379, this is strongly discouraged!
ago 01 10:05:51 localhost.localdomain systemd[1]: Started etcd service.

As you may notice there’s a warning about “serving insecure client requests on localhost:2379, this is strongly discouraged!” once again please change the configuration for your needs and set it safely.

I’ll try update this post so you may follow this blog.

Cheers!

Service definition to run Cockpit on system startup for CentOS Atomic SIG

I’m working these days with Project Atomic. You should have a look to the awesome Quickstart guide.

I’ve chosen to use Vagrant with the CentOS Atomic SIG so playing with Project Atomic is really easy (change to virtualbox if using that provider :D)

vagrant init centos/atomic-host; vagrant up –provider libvirt

One of the first things I’ve tested is Cockpit’s web server manager. It’s pretty cool and easy to install following the guide.

Once inside the Project Atomic host, Cockpit’s container is intalled with the following command:

vagrant ssh
sudo atomic run cockpit/ws

Remember, I use this blog so I don’t forget my notes. I’m just sharing with you the service definition needed to run Cockpit on system startup when working with CentOS Atomic SIG and not Fedora’s version which is explained in the source for this post. This file must be placed at /etc/systemd/system/cockpitws.service

[Unit]
Description=Cockpit Web Interface
Requires=docker.service
After=docker.service

[Service]
Restart=on-failure
RestartSec=10
ExecStart=/usr/bin/docker run --rm --privileged --pid host -v /:/host --name %p cockpit/ws /container/atomic-run --local-ssh
ExecStop=-/usr/bin/docker stop -t 2 %p

[Install]
WantedBy=multi-user.target

Then just enable and start the service and the Cockpit container will run and be ready to serve at 9090 port (user vagrant/vagrant or root/vagrant).

sudo systemctl daemon-reload
sudo systemctl enable cockpitws.service
sudo systemctl start cockpitws.service

cockpit_inicio

Cool stuff Project Atomic and Cockpit.

 

 

Installing NGINX on CentOS 7

This a quick note on how to install the latest NGINX server on my CentOS 7, using the pakages provided by the NGINX team.  I share this post as it may help any visitor.

The official info about the official NGINX packages is in NGINX’s site

As root you can add the repository file for mainline version:

cat << EOT > /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/\$basearch/
gpgcheck=0
enabled=1
EOT

If you want to use the stable version you’d execute:

cat << EOT > /etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/\$basearch/
gpgcheck=0
enabled=1
EOT

Then just use yum:

yum install -y nginx

And manage the service as usual (start the service, enable it at boot time and check the status):

service start nginx

service enable nginx

service status nginx

If you want to check the version you’ve just installed (e.g I’m using the latest mainline version July/2016):

# nginx -v
nginx version: nginx/1.11.2

And that’s all, just a note for my reference for the future, hope it helps you too 🙂

 

Installing Cobbler in CentOS 7

I’m evaluating Cobbler as my Linux installation and inventory server for my Configuration Management Database. I’ve heard good things about Cobbler and for now I’d like to share my installation steps with you. In this post I’m covering installation for cobbler and cobbler’s web interface.

Note: I’ll be updating this article if I found anything is missing, so please contact me with your feedback so I can add corrections.

Cobbler is available at the EPEL repository:

yum install epel-release -y

We’ll need some packages:

yum install cobbler cobbler-web pykickstart fence-agents xinetd setroubleshoot-server firewalld wget perl-LockFile-Simple perl-IO-Compress perl-Compress-Raw-Zlib perl-Digest-MD5 perl-Digest-SHA perl-Net-INET6Glue perl-LWP-Protocol-https -y

If you want to manage Debian/Ubuntu repositories, the debmirror script must be installed. It’s a perl script which can be downloaded from the Debian repository (look for the most recent version that fits you):

cd /tmp
wget http://ftp.es.debian.org/debian/pool/main/d/debmirror/debmirror_2.20.tar.xz
tar xf debmirror_2.30.tar.xz
cp debmirror/debmirror /usr/bin/

Cobbler uses Apache, and a TFTP server will be run using the xinetd server so we’ll enable and start some systemd services:

systemctl enable cobblerd
systemctl enable httpd
systemctl enable xinetd

systemctl start firewalld

I’ll add a firewall rule so my http and https services are open:

firewall-cmd  --add-service http  --permanent
firewall-cmd  --add-service https --permanent
firewall-cmd --reload

SELinux –> If you follow my blog, you know I like to have SELinux running, so you can skip any block starting with SELinux in bolded letters. We’ll need the following booleans:

setsebool -P httpd_can_network_connect_cobbler 1
setsebool -P httpd_serve_cobbler_files 1

Time to start both Apache and Cobblerd:

systemctl start httpd
systemctl start cobblerd

We can check if cobbler is working:

cobbler --version (two dashes)

Cobbler 2.6.11
source: ?, ?
build time: Sun Jan 24 14:40:17 2016

We’ll need to configure a few things now. Set the IP address, your server will listen on. In my lab, the IP address is 192.168.2.1 so change it accordingly.

sed -i.bak ‘s/server: 127\.0\.0\.1/server: 192\.168\.2\.1/g’ /etc/cobbler/settings

The TFTP server will be started thanks to the Xinetd server:

sed -i.bak ‘/disable/c\\tdisable\t\t\t= no’ /etc/xinetd.d/tftp

systemctl start xinetd

We can download several network boot-loaders:

cobbler get-loaders (to download several network boot-loaders)

We can generate a new default password, choose a passprase and the password you prefer!

openssl passwd -1 -salt ‘A random passphrase, choose yours’ ‘your-password-here’ > /tmp/random_pass

sed -i.bak “/default_password_crypted:/c\default_password_crypted: \”$(cat /tmp/random_pass)\”” /etc/cobbler/settings

Once all the changes have been saved, restart the cobblerd daemon:

systemctl restart cobblerd

Now we can run a check to test if our configuration is good and ready. As I’m using SELinux I don’t care about the warning on “SELinux is enabled”.

cobbler check

The following are potential configuration items that you may want to fix:

1 : SELinux is enabled. Please review the following wiki page for details on ensuring cobbler works correctly in your SELinux environment:
https://github.com/cobbler/cobbler/wiki/Selinux

SELinux –> We have to add a new policy to avoid some SELinux issues.

yum install -y selinux-policy-devel

mkdir /root/policy
cd /root/policy
cat <<EOT > /root/policy/cobbler-web.te
policy_module(cobbler-web, 1.0)

gen_require(\`
type cobblerd_t;
type systemd_unit_file_t;
‘)

allow cobblerd_t systemd_unit_file_t:file getattr;
EOT

make -f /usr/share/selinux/devel/Makefile cobbler-web.pp

semodule -i cobbler-web.pp

Finally open the following URL, in my example my server is called cobbler.artemit.local. Please change your server name or IP address to one that fits your environment:

https://cobbler.artemit.local/cobbler_web

A certificate has been generated for SomeOrganization and it’s valid for 1 year, so deal with your browser’s SSL warning.

cobbler_screenshot

The default user is cobbler and the default password is cobbler.

That’s all for now, I’ll write some lines about configuration later, but don’t forget to read the official documentation.

 

CentOS 7 – Installing Floodlight

Hi there!,
In the following weeks, I’ll be using the Floodlight controller to develop some code to get a deeper understanding on Software-Defined Networks. In my lab environment I’ll using OpenFlow to configure some OpenVswitch virtual switches.

In this post I’m showing you how I’ve installed Floodlight on my CentOS 7 machine, creating a service, configuring logging and more.

Let’s begin installing some development tools, Git, Java and Ant:

yum group install -y "Development Tools"
yum -y install git
yum install -y java-1.7.0-openjdk ant

We need Floodlight’s source code and then we’ll build it:

cd /opt
git clone git://github.com/floodlight/floodlight.git
cd floodlight/
ant

...
Buildfile: /opt/floodlight/build.xml
init:
...
[jar] Building jar: /opt/floodlight/target/floodlight.jar
...
BUILD SUCCESSFUL
Total time: 50 seconds

Awesome, Floodlight was built succesfully. We’ll now create some directories:

mkdir /var/lib/floodlight
mkdir /etc/floodlight
mkdir /var/log/floodlight/

OpenFlow protocol will use IANA’s reserved port 6653. I’ll add a rule allowing that traffic from my management network 192.168.4.0/24:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.4.0/24" port port="6653" protocol="tcp" accept'

firewall-cmd --reload

Also, if using the REST API (HTTP) or using the web user interface, we’ll need a rule allowing traffic on port 8080. In my lab, I’ll add a rule to allow traffic from my development network 192.168.5.0/24:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.5.0/24" port port="8080" protocol="tcp" accept'

firewall-cmd --reload

Next. Let’s add a user called, guess it? floodlight!, set the JAVA_HOME and change some directories ownership:

useradd floodlight
echo 'export JAVA_HOME=/usr/lib/jvm/jre-openjdk' >> /home/floodlight/.bash_profile 

chown -R floodlight:floodlight /opt/floodlight
chown -R floodlight:floodlight /var/lib/floodlight
chown -R floodlight:floodlight /var/log/floodlight
chown -R floodlight:floodlight /etc/floodlight

Now let’s open a shell using our floodlight user:

su - floodlight

Let’s copy the default floodlight’s properties file to our /etc/floodlight directory:

cp /opt/floodlight/src/main/resources/floodlightdefault.properties /etc/floodlight/

Let’s start Floodlight for the first time, specifying where’s our properties file. If everything is OK we’ll see some info and warning messages:

java -jar /opt/floodlight/target/floodlight.jar -cf /etc/floodlight/floodlightdefault.properties
...
11:00:08.221 INFO [n.f.c.m.FloodlightModuleLoader:main] Loading modules from /etc/floodlight/floodlightdefault.properties
11:00:08.702 WARN [n.f.r.RestApiServer:main] HTTPS disabled; HTTPS will not be used to connect to the REST API.
11:00:08.702 WARN [n.f.r.RestApiServer:main] HTTP enabled; Allowing unsecure access to REST API on port 8080.
11:00:19.552 WARN [n.f.c.i.OFSwitchManager:main] SSL disabled. Using unsecure connections between Floodlight and switches.
...
11:00:19.603 INFO [n.f.c.i.Controller:main] Controller role set to ACTIVE
...
11:00:19.716 INFO [n.f.f.Forwarding:main] Default flow matches set to: VLAN=true, MAC=true, IP=true, TPPT=true
11:00:20.572 INFO [o.s.s.i.r.RPCService:main] Listening for internal floodlight RPC on localhost/127.0.0.1:6642
11:00:20.812 INFO [n.f.c.i.OFSwitchManager:main] Listening for switch connections on 0.0.0.0/0.0.0.0:6653
11:00:20.831 INFO [n.f.l.i.LinkDiscoveryManager:main] Setting autoportfast feature to OFF
11:00:35.997 INFO [n.f.l.i.LinkDiscoveryManager:Scheduled-1] Sending LLDP packets out of all the enabled ports
11:00:37.959 INFO [n.f.j.JythonServer:debugserver-main] Starting DebugServer on :6655

If using the default properties, we’ll now have an active OpenFlow controller with a Forwarding module that allows our virtual switches (if using Floodlight as the controller, of course!) to forward ethernet frames.

As an example, these are information messages when the first switch connects to Floodlight:

11:15:13.041 INFO [n.f.c.i.OFChannelHandler:New I/O worker #11] New switch connection from /192.168.4.2:44893
11:15:13.201 INFO [n.f.c.i.OFSwitchHandshakeHandler:New I/O worker #11] Switch OFSwitchBase DPID[00:00:bc:30:5b:da:eb:60] bound to class class net.floodlightcontroller.core.OFSwitch, description SwitchDescription [manufacturerDescription=Nicira, Inc., hardwareDescription=Open vSwitch, softwareDescription=2.3.1, serialNumber=None, datapathDescription=None]

Once we’ve checked that Floodlight can be started we’ll kill the process using Ctrl-C and close our session.

^C[floodlight@tornasol ~]$ exit

I’m not using floodlight as an interactive user anymore so I’ll remove the shell:

usermod -s /sbin/nologin floodlight

Floodlight by default, will use standard output to write many messages. I want to reduce log level and set a file where logs will be written. Thanks to the information provided by Volkan Yazici and Luca Prete in this Google’s group, these are the steps I’ve followed.

First I create a backup file for the /opt/floodlight/logback.xml file:

cp /opt/floodlight/logback.xml /opt/floodlight/logback.xml.orig

Then I create a new /opt/floodlight/logback.xml file with the following content. Basically I’m reducing the log level so only INFO and WARN messages are sent to /var/log/floodlight/floodlight.log and no messages are sent to standard output:

cat <<EOT > /opt/floodlight/logback.xml
<configuration scan="true">
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>/var/log/floodlight/floodlight.log</file>
<encoder>
<pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
<logger name="org" level="WARN"/>
<logger name="LogService" level="WARN"/> <!-- Restlet access logging -->
<logger name="net.floodlightcontroller" level="INFO"/>
<logger name="net.floodlightcontroller.logging" level="WARN"/>
</configuration>
EOT

Ok. Now we’ll create a systemd service so Floodlight is started and stopped nicely. I’m specifying where is the configuration file for logback and where’s the properties file.

cat <<EOT > /etc/systemd/system/floodlight.service
[Unit]
Description=FloodLight Service 
After=network.target
[Service]
EnvironmentFile=/etc/sysconfig/floodlight
User=floodlight
WorkingDirectory=/etc/floodlight
ExecStart=/usr/bin/java -Dlogback.configurationFile=/opt/floodlight/logback.xml -jar /opt/floodlight/target/floodlight.jar -cf /etc/floodlight/floodlightdefault.properties
Restart=on-abort
[Install]
WantedBy=multi-user.target
EOT

We’ll create the /etc/sysconfig/floodlight file so we’re sure that the JAVA_HOME environment variable is properly used:

cat <<EOT > /etc/sysconfig/floodlight
JAVA_HOME=/usr/lib/jvm/jre-openjdk
EOT

Let’s cross our fingers. Starting the service and checking status:

systemctl start floodlight.service

systemctl status floodlight.service

Floodlight service started

Looks good! Let’s enable service start at boot time:

systemctl enable floodlight.service

I think it’s a good idea to add a logrotate.d file so our Floodlight’s log file is rotated. I’ll use libvirtd file as a template to create the /etc/logrotate.d/floodlight file:

/var/log/floodlight/floodlight.log {
weekly
missingok
rotate 4
compress
delaycompress
copytruncate
minsize 100k
}

Finally I’ll check that the web user interface is listening on the 8080 port and that I’ve information about my OpenFlow switches (URL http://x.x.x.x:8080/ui/index.html, use your IP address of course!)

floodlight ui

OK. Nice!, now I’m ready to start developing. I’ll post any useful information about Floodlight’s development or usage in my blog, but you should start visiting the official page, as I’m going to do right now 😀

Cheers!

CENTOS 7 – USING THE POWERDNS WEB API TO ADD AND EDIT RECORDS

In a previous post I’ve talked about how to install PowerDNS on a CentOS 7 as both recursive and authoritative server for my lab environment.

In this post I’ll explain you how I use the experimental web API to add records to my DNS authoritative server to solve requests for a local domain called artemit.local.

I’m using the official documentation as a reference but also adding more examples so they can be helpful for you (I’ll be updating this post from time to time). The PowerDNS server has a web server listening on the 127.0.0.1 address port 8081 and I’ll use curl to use the API.

Important: Please replace changeme to the API key you had configured

  1. Adding or editing a new zone/domain called artemit.local and assigning a name server called ns1.artemit.local
    curl -X POST --data '{"name":"artemit.local", "kind": "Master","dnssec":false,"soa-edit":"INCEPTION-INCREMENT","masters": [], "nameservers": ["ns1.artemit.local"]}' -v -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones | jq .
  2. Adding or editing a Start Of Authority (SOA) record for the artemit.local domain. The name server is ns1.artemit.local and the contact mail address is hostmaster.artemit.com.es.
    curl -X PATCH --data '{"rrsets": [ {"name": "artemit.local", "type": "SOA", "changetype": "REPLACE", "records": [ {"content": "ns1.artemit.local hostmaster.artemit.com.es 0 10800 3600 604800 3600", "disabled": false, "name": "artemit.local", "ttl": 86400, "type": "SOA", "priority": 0 } ] } ] }' -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones/artemit.local | jq .
  3. Adding or editing an address record (A) so ns1.artemit.local record has the IP address 192.168.4.4
    curl -X PATCH --data '{"rrsets": [ {"name": "ns1.artemit.local", "type": "A", "changetype": "REPLACE", "records": [ {"content": "192.168.4.4", "disabled": false, "name": "ns1.artemit.local", "ttl": 86400, "type": "A", "priority": 0 } ] } ] }' -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones/artemit.local | jq .
  4. Adding or editing an alias record (CNAME) so tornasol.artemit.local has the same IP address as ns1.artemit.local.
    curl -X PATCH --data '{"rrsets": [ {"name": "tornasol.artemit.local", "type": "CNAME", "changetype": "REPLACE", "records": [ {"content": "ns1.artemit.local", "disabled": false, "name":"tornasol.artemit.local", "ttl": 86400, "type": "CNAME", "priority": 0 } ] } ] }' -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones/artemit.local | jq .
  5. Adding or editing a reverse lookup zone/domain if you want to ask for the hostname for an IP address in the 192.168.4.0/24 network:
    curl
    -X POST --data '{"name":"4.168.192.in-addr.arpa",
    "kind":
    "Master","dnssec":false,"soa-edit":"INCEPTION-INCREMENT","masters":
    [], "nameservers": ["ns1.artemit.local"]}' -v -H
    'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones
    | jq .
  6. Adding or editing the SOA for the reverse lookup:
    curl -X PATCH --data '{"rrsets": [ {"name": "4.168.192.in-addr.arpa", "type": "SOA", "changetype": "REPLACE", "records": [ {"content": "ns1.artemit.local hostmaster.artemit.com.es 0 10800 3600 604800 3600", "disabled": false, "name": "4.168.192.in-addr.arpa", "ttl": 86400, "type": "SOA", "priority": 0 } ] } ] }' -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones/4.168.192.in-addr.arpa | jq .
  7. Adding or editing a reverse PTR record (e.g when asking for the 192.168.4.4 IP address we’ll get ns1.artemit.local
  8. curl -X PATCH --data '{"rrsets": [ {"name": "4.4.168.192.in-addr.arpa", "type": "PTR", "changetype": "REPLACE", "records": [ {"content": "ns1.artemit.local", "disabled": false, "name": "4.4.168.192.in-addr.arpa", "ttl": 86400, "type": "PTR", "priority": 0 } ] } ] }' -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones/4.168.192.in-addr.arpa | jq .
  9. Deleting a zone/domain (e.g artemit.local)
curl -X DELETE -v -H 'X-API-Key: changeme' http://127.0.0.1:8081/servers/localhost/zones/artemit.local | jq .

Mmmm. Don’t like these commands? Well I can’t blame you however I find them useful as I’m preparing a Python script to help you to manage PowerDNS easily (check my GitHub account from time to time). Don’t worry, you have some web GUIs and you can always add records using your favourite PostgreSQL client.

Enjoy!

CentOS 7 – Installing and configuring PowerDNS with PostgreSQL

In my lab I like to use DNS servers rather than hosts files and dnsmasq. In the past I’ve used djbdns but I wanted to learn something new so I’ve decided to have a look at PowerDNS.

PowerDNS runs fine, it’s quite easy to install and has great documentation so here are the steps I’ve followed in my CentOS 7 host using PostgreSQL as the database backend (MariaDB/MySQL is also supported!).

In this post I’m using two PowerDNS servers:

  1. DNS authoritative server to answer the DNS requests for my local domain called artemit.local (e.g tornasol.artemit.local)
  2. DNS recursive server to answer and save in cache the DNS requests for other domains like those on Internet (e.g google.com).

PowerDNS is available at the EPEL repository:

yum install -y epel-release

yum -y install pdns pdns-tools pdns-backend-postgresql pdns-recursor net-tools bind-utils jq

We’ll need to create a postgres database so we’ll use the postgres user and execute some commands from the psql CLI. I’ll name the database pdns.

su - postgres

-bash-4.2$ psql
psql (9.2.10)
postgres=# CREATE DATABASE pdns;
CREATE DATABASE
postgres=# \q

We’ll load the schema available in the /usr/share/doc folder. When you install the pdns package the version number may have been changed so replace 3.4.4 accordingly:

-bash-4.2$ psql pdns < /usr/share/doc/pdns-backend-postgresql-3.4.4/schema.pgsql.sql

We’ll create a user called pdns and will grant the right permissions. Important!: Replace xxxxxxx with your password 😀

-bash-4.2$ psql
postgres=# \c pdns
pdns=# CREATE USER pdns WITH PASSWORD 'xxxxxxx';
CREATE ROLE
pdns=# GRANT ALL ON DATABASE "pdns" TO pdns;
pdns=# GRANT ALL ON ALL TABLES IN SCHEMA public TO pdns;
pdns=# GRANT ALL ON ALL SEQUENCES IN SCHEMA public TO pdnsGRANT
pdns=#\c postgres
postgres=# \q

Let’s close the postgres user session:

-bash-4.2$ exit

We need to edit the following line in the /var/lib/pgsql/data/pg_hba.conf file, and change the ident keyword to  trust:

host all all 127.0.0.1/32 trust

Let’s restart the PostgreSQL server:

systemctl restart postgresql.service

Now we’ll modify the /etc/pdns/pdns.conf file adding the following lines at the end, but first let’s explain what we’re doing:

  • We’re the database backend. My PostgreSQL server is listening in the 127.0.0.1 IP address by default. The database is named pdns and the user is named pdns too. The pdns password should be changed with the one you’ve set before!
  • My server is listening for authoritative DNS requests on the 192.168.4.4 address (local address).
  • My server is listening for recursive DNS requests on the 127.0.0.1 address (recursor)
  • In my example I’m allowing the hosts on the 192.168.4.0/24 to query my DNS recursive server.
  • We’re using a experimental web API to add DNS records. The web API uses by default the changeme password, but you can use another one!
launch=gpgsql
allow-recursion=192.168.4.0/24
recursor=127.0.0.1
local-address=192.168.4.4
gpgsql-host=127.0.0.1
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password=xxxxxxx
experimental-json-interface=yes
experimental-api-key=changeme
webserver=yes

We also need to add the following entry to the /etc/pdns-recursor/recursor.conf file so recursive queries are allowed for the localhost and the 192.168.4.0/24 network:

allow-from=127.0.0.0/8, 192.168.4.0/24

Now we’ll enable the pdns and pdns-recursor to start at boot time:

systemctl enable pdns.service
systemctl enable pdns-recursor.service

Let’s start the services:

systemctl start pdns.service
systemctl start pdns-recursor.service

Let’s check the status of both servers:

systemctl -l status pdns.service
pdns.service - PowerDNS Authoritative Server
Loaded: loaded (/usr/lib/systemd/system/pdns.service; enabled)
Active: active (running) since dom 2015-04-05 18:08:09 CEST; 985ms ago
[...]

systemctl -l status pdns-recursor.service
pdns-recursor.service - PowerDNS recursing nameserver
Loaded: loaded (/usr/lib/systemd/system/pdns-recursor.service; enabled)
Active: active (running) since dom 2015-04-05 17:36:27 CEST; 33min ago
[...]

Let’s check that both DNS servers are listening on TCP and UDP 53 ports and that the PostgreSQL is being reached by the PowerDNS servers:

netstat -ntuap | grep dns
tcp 0 0 127.0.0.1:8081 0.0.0.0:* LISTEN 15366/pdns_server
tcp 0 0 192.168.4.4:53 0.0.0.0:* LISTEN 15366/pdns_server
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN 13964/pdns_recursor
tcp 0 0 127.0.0.1:34150 127.0.0.1:5432 ESTABLISHED 15366/pdns_server
tcp 0 0 127.0.0.1:34147 127.0.0.1:5432 ESTABLISHED 15366/pdns_server
tcp 0 0 127.0.0.1:34148 127.0.0.1:5432 ESTABLISHED 15366/pdns_server
tcp 0 0 127.0.0.1:34149 127.0.0.1:5432 ESTABLISHED 15366/pdns_server
udp 0 0 192.168.4.4:53 0.0.0.0:* 15366/pdns_server
udp 0 0 127.0.0.1:53 0.0.0.0:* 13964/pdns_recursor
udp 0 0 127.0.0.1:49594 127.0.0.1:53 ESTABLISHED 15366/pdns_server

Let’s open ports in our firewall. My 192.168.4.0/24 is allowed, that’s why I use it as the source address:

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.4.0/24" port port="53" protocol="udp" accept'

firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.4.0/24" port port="53" protocol="tcp" accept'

firewall-cmd --reload

Don’t forget to add or edit the DNS server for your host. For example you can add a DNS1 entry to the network script at /etc/sysconfig/network-scripts/ifcfg-eth0 and change the entry to DNS1=192.168.4.4 or any other IP you’ve set for your PowerDNS server.

Wait a minute! And how I can add entries for my local domain?

There are some web interfaces for PowerDNS but I do love CLI so I’ll using some commands to use the experimental web API to add and edit DNS records. But this post is long enough, continue here to know more.