Showing posts with label F22. Show all posts
Showing posts with label F22. Show all posts

Symfony Installation For Developer and System Administrator

Symfony, the PHP framework which has won the PHP framework market share as quite a few crucial PHP projects already transitioned or use either Symfony2 framework or its components. While I'm not a fan of Symfony due to its Javaism which introduces unnecessary complexity and divert from the original PHP design principles, but you can't ignore the influences it brought to PHP world.

Four years ago, I was evaluating it for a new project, but decided to go with CodeIgniter and Kohana due to project size and time frame. Always go for something you're familiar with instead venturing into new unknown territory. The money and time spent does not justify it. Everyone wants it fast, cheat, and don't really care about longevity of any projects. Enough ramblings, let us revisit the installation.

There are many ways to install or use Symfony framework but the recommended way is to use the Symfony installer. Although installation through Composer (deprecated), PEAR (deprecated), or GNU/Linux distros packages are still feasible.

First, getting the Symfony installer which you can obtain by downloading the binary directly and install locally. Popularized by those developer who want to have a universal quick installation method between GNU/Linux and MacOS. The Curl's -LsS parameter means that to download from a location (-L), silently (-s), but show errors (-S). Go to Explain Shell for the full parameters details.
$ sudo curl -LsS http://symfony.com/installer -o /usr/local/bin/symfony
$ sudo chmod a+x /usr/local/bin/symfony

Quick and convenient right? Indeed for developer point of view who want to bootstrap any application using Symfony framework quickly. However, for a system administrator, this is a big no-no, especially in production server, where priorities are targeted towards stability and security. Why so? Note that we should always verify the authenticity of any downloaded installer to check for any corruption or tampering. While there is way to verify Symfony components, we can't seem to find it for Symfony installer. Hence, such installation method, while convenient, lack assurances.

If you're a system administrator, surely you will prefer the default packages that come with your GNU/Linux distros. For sure, you are guarantee of well-tested and automated security updates. Something that is not possible if you install the Symfony framework manually where you've to keep track of any security advisories. The trade-off is that you've to stick with legacy but stable version of the framework which may not be supported anymore.

For example, in Fedora 22, which was release few weeks back, the available Symfony version is 2.5.11. Unfortunately, after checking release schedule and roadmap checker, there will be no support of security fixes after July 2015 and is advisable to upgrade to version 2.7.x.
$ dnf info php-symfony | grep Version
Version     : 2.5.11

If you're starting a new Symfony project, are you going to use the default and outdated Symfony packages that comes with your distro? Surely not. Who in the right mind will develop against an unsupported version? And furthermore, developer always like fancy new toys.

This is one of the dilemma when the distro packages is not catching up with the release cycle of the software. Another good example is in Fedora 22, there are still packages for PEAR channel for Symfony, where this is not supported anymore due to the transition to Composer. I'm not sure why Symfony 2.5 was selected but obviously there is a mismatch between the Fedora 22 and Symfony release timeline. Also, I think Centos 6 or 7 will have the similar unsupported version.
$ dnf search symfony | grep channel
php-channel-symfony.noarch : Adds symfony project channel to PEAR
php-channel-symfony2.noarch : Adds pear.symfony.com channel to PEAR

In the end, stick to the simpler way, using the Symfony installer, even though you may be some security risk but that can be prevented by verifying its components and using Security Advisories Checker tool..

Linux Containers (LXC) in Fedora 22 Rawhide - Part 3

Continue from Part 1 and Part 2. We'll discuss another issue caused by the default LXC installation in Fedora 22, which is no default bridge network created although one is set in the config file for each container.

Let's create a dummy container to view the default bridge network interface.
$ sudo lxc-create -t download -n foo -- -d centos -r 6 -a amd64
$ sudo cat /var/lib/lxc/foo/config | grep lxc.network.link
lxc.network.link = lxcbr0

However, as I mentioned earlier, the bridge interface lxcbr0 is not created by default. Note that bridge interface virbr0 was created due to libvirt installation.
$ ip link show | grep br0
6: virbr0:  mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default 
7: virbr0-nic:  mtu 1500 qdisc fq_codel master virbr0 state DOWN mode DEFAULT group default qlen 500

Or you can use the brctl command to show the available bridge interface. If you can't find the command, just install the bridge-utils package.
$ sudo dnf install bridge-utils
$ brctl show
bridge name     bridge id               STP enabled     interfaces
virbr0          8000.525400c28250       yes             virbr0-nic

Instead of changing the default lxc.network.link item in the container's config file every time we create a container, we can use two ways to resolve this issue. First, by overwrite the default network interface name. Second, is to create the lxcbr0 bridge interface manually.

For the first method, just overwrite the default network interface name.
$ sudo sed -i s/lxcbr0/virbr0/g /etc/lxc/default.conf 
$ cat /etc/lxc/default.conf | grep lxc.network.link
lxc.network.link = virbr0

The issue is such approach is that you'll share the same bridge network interface with libvirt which primary manages KVM (Kernel-based Virtual Machine). Thus, if you need additional customization, for example, like different IP range, is best to create a bridge network interface, which, leads us to the second method.

First, let's duplicate the XML file that define the default bridge network.
sudo cp /etc/libvirt/qemu/networks/default.xml /etc/libvirt/qemu/networks/lxcbr0.xml

Next, we need to generate a random UUID, Universal unique identifier and MAC, media access control address for our new bridge network interface named lxcbr0.

Generating UUID.
$ uuidgen
5df6886c-1dfe-44ca-8865-ebed91bd2646

Generating MAC address.
$ MACADDR="52:54:$(dd if=/dev/urandom count=1 2>/dev/null | md5sum | sed 's/^\(..\)\(..\)\(..\)\(..\).*$/\1:\2:\3:\4/')"; echo $MACADDR
52:54:f0:ec:cb:a3

Update the lxcbr0.xml file we've just duplicated and add in both the UUID and MAC address to the file.

The final XML file as shown below:
<!--
WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
OVERWRITTEN AND LOST. Changes to this xml configuration should be made using:
  virsh net-edit lxcbr0
or other application using the libvirt API.
-->

<network>
  <name>lxcbr0</name>
  <uuid>5df6886c-1dfe-44ca-8865-ebed91bd2646</uuid>
  <forward mode='nat'/>
  <bridge name='lxcbr0' stp='on' delay='0'/>
  <mac address='52:54:f0:ec:cb:a3'/>
  <ip address='192.168.125.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.125.2' end='192.168.125.254'/>
    </dhcp>
  </ip>
</network>

Enable, auto start, and start the lxcbr0 bridge interface.
$ sudo virsh net-define /etc/libvirt/qemu/networks/lxcbr0.xml
$ sudo virsh net-autostart lxcbr0
$ sudo virsh net-start lxcbr0

Now both bridge interfaces were created and enabled. You can create any container using the default lxcbr0 bridge network interface.
$ brctl show
bridge name     bridge id               STP enabled     interfaces
lxcbr0          8000.00602f7e384b       yes             lxcbr0-nic
virbr0          8000.525400c28250       yes             veth1HV308
                                                        virbr0-nic

There are many other ways to create and setup a bridge network interface but the method of using virsh command is probably the easiest and fastest. All the necessary steps to configure DHCP through Dnsmasq has been automated. As observed through the Dnsmasq instance after we've started the lxcbr0 bridge network interface.
$ ps aux | grep [l]xcbr0
nobody    9443  0.0  0.0  20500  2424 ?        S    01:08   0:00 /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/lxcbr0.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
root      9444  0.0  0.0  20472   208 ?        S    01:08   0:00  \_ /sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/lxcbr0.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper

Details of the lxcbr0.conf file.
$ sudo cat /var/lib/libvirt/dnsmasq/lxcbr0.conf 
##WARNING:  THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
##OVERWRITTEN AND LOST.  Changes to this configuration should be made using:
##    virsh net-edit lxcbr0
## or other application using the libvirt API.
##
## dnsmasq conf file created by libvirt
strict-order
pid-file=/var/run/libvirt/network/lxcbr0.pid
except-interface=lo
bind-dynamic
interface=lxcbr0
dhcp-range=192.168.125.2,192.168.125.254
dhcp-no-override
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/lxcbr0.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/lxcbr0.addnhosts

Linux Containers (LXC) in Fedora 22 Rawhide - Part 1

While Docker, an application container is widely popular right now, I've decided to try LXC, a machine container that hold a virtual machine like VirtualBox or WMWare but with near bare-metal performance. As I was running on Fedora Rawhide (F22), let's try to install and setup LXC in this distro.

Installation is pretty much straight forward.
$ sudo dnf install lxc lxc-templates lxc-extra

Checking our installed version against the latest available version. Our installed version on par with the current release.
$ lxc-ls --version
1.1.2

The first thing to do is to check our LXC configuration. As emphasized in red below, the Cgroup memory controller is not enabled by default as it will incur additional memory. This can be enabled through by adding boot parameter cgroup_enable=memory to the Grub boot loader. For now, we will keep that in mind and stick to the default.
$ lxc-checkconfig

Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-4.0.1-300.fc22.x86_64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
Multiple /dev/pts instances: enabled

--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: missing
Cgroup cpuset: enabled

--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
File capabilities: enabled

Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

Before we can create our container, let's find out the available templates or GNU/Linux distros we can create.
$ ll /usr/share/lxc/templates/
total 348K
-rwxr-xr-x. 1 root root  11K Apr 24 03:22 lxc-alpine*
-rwxr-xr-x. 1 root root  14K Apr 24 03:22 lxc-altlinux*
-rwxr-xr-x. 1 root root  11K Apr 24 03:22 lxc-archlinux*
-rwxr-xr-x. 1 root root 9.5K Apr 24 03:22 lxc-busybox*
-rwxr-xr-x. 1 root root  29K Apr 24 03:22 lxc-centos*
-rwxr-xr-x. 1 root root  11K Apr 24 03:22 lxc-cirros*
-rwxr-xr-x. 1 root root  17K Apr 24 03:22 lxc-debian*
-rwxr-xr-x. 1 root root  18K Apr 24 03:22 lxc-download*
-rwxr-xr-x. 1 root root  48K Apr 24 03:22 lxc-fedora*
-rwxr-xr-x. 1 root root  28K Apr 24 03:22 lxc-gentoo*
-rwxr-xr-x. 1 root root  14K Apr 24 03:22 lxc-openmandriva*
-rwxr-xr-x. 1 root root  15K Apr 24 03:22 lxc-opensuse*
-rwxr-xr-x. 1 root root  40K Apr 24 03:22 lxc-oracle*
-rwxr-xr-x. 1 root root  11K Apr 24 03:22 lxc-plamo*
-rwxr-xr-x. 1 root root 6.7K Apr 24 03:22 lxc-sshd*
-rwxr-xr-x. 1 root root  25K Apr 24 03:22 lxc-ubuntu*
-rwxr-xr-x. 1 root root  13K Apr 24 03:22 lxc-ubuntu-cloud*

Let's proceed ahead by create our first container, a CentOS 6 distro. Unfortunately, as seen below, the creation failed due to deprecation of the Yum command which was redirected to DNF command.
$ sudo lxc-create -t centos -n centos-test

Host CPE ID from /etc/os-release: cpe:/o:fedoraproject:fedora:22
This is not a CentOS or Redhat host and release is missing, defaulting to 6 use -R|--release to specify release
Checking cache download in /var/cache/lxc/centos/x86_64/6/rootfs ... 
Downloading centos minimal ...
Yum command has been deprecated, redirecting to '/usr/bin/dnf -h'.
See 'man dnf' and 'man yum2dnf' for more information.
To transfer transaction metadata from yum to DNF, run:
'dnf install python-dnf-plugins-extras-migrate && dnf-2 migrate'

Yum command has been deprecated, redirecting to '/usr/bin/dnf --installroot /var/cache/lxc/centos/x86_64/6/partial -y --nogpgcheck install yum initscripts passwd rsyslog vim-minimal openssh-server openssh-clients dhclient chkconfig rootfiles policycoreutils'.
See 'man dnf' and 'man yum2dnf' for more information.
To transfer transaction metadata from yum to DNF, run:
'dnf install python-dnf-plugins-extras-migrate && dnf-2 migrate'

Config error: releasever not given and can not be detected from the installroot.
Failed to download the rootfs, aborting.
Failed to download 'centos base'
failed to install centos
lxc-create: lxccontainer.c: create_run_template: 1202 container creation template for centos-test failed
lxc-create: lxc_create.c: main: 274 Error creating container centos-test

The above error is a good example on why the transition from YUM to DNF command was unnecessary and caused breakage. It turned out that /usr/bin/yum is a shell script that display notification message. To resolve this, we need to point /usr/bin/yum to the actual yum program. There are way to bypass this step where we'll discuss about this in Part 2.
$ sudo mv /usr/bin/yum /usr/bin/yum2dnf
$ sudo ln -s /usr/bin/yum-deprecated /usr/bin/yum
$ ll /usr/bin/yum
lrwxrwxrwx. 1 root root 23 May  5 23:40 /usr/bin/yum -> /usr/bin/yum-deprecated*

Let's us try again. Although there is notification, the creation of the container will run smoothly. Since we're creating this for the first time, it will took a while to download all the packages.
$ sudo lxc-create -t centos -n centos-test
......
Complete!
Download complete.
Copy /var/cache/lxc/centos/x86_64/6/rootfs to /var/lib/lxc/centos-test/rootfs ... 
Copying rootfs to /var/lib/lxc/centos-test/rootfs ...
Storing root password in '/var/lib/lxc/centos-test/tmp_root_pass'
Expiring password for user root.
passwd: Success

Container rootfs and config have been created.
Edit the config file to check/enable networking setup.

The temporary root password is stored in:

        '/var/lib/lxc/centos-test/tmp_root_pass'

The root password is set up as expired and will require it to be changed
at first login, which you should do as soon as possible.  If you lose the
root password or wish to change it without starting the container, you
can change it from the host by running the following command (which will
also reset the expired flag):

        chroot /var/lib/lxc/centos-test/rootfs passwd

Checking our newly created container.
$ sudo lxc-ls
centos-test  

Checking the container status.
$ sudo lxc-info -n centos-test
Name:           centos-test
State:          STOPPED

Start our newly created container. Yet again, another error.
$ sudo lxc-start -n centos-test
lxc-start: lxc_start.c: main: 344 The container failed to start.
lxc-start: lxc_start.c: main: 346 To get more details, run the container in foreground mode.
lxc-start: lxc_start.c: main: 348 Additional information can be obtained by setting the --logfile and --logpriority options.

Let's try again, but with foreground mode (-F).
$ sudo lxc-start -F -n centos-test
lxc-start: conf.c: instantiate_veth: 2672 failed to attach 'vethM9Q6RT' to the bridge 'lxcbr0': Operation not permitted
lxc-start: conf.c: lxc_create_network: 2955 failed to create netdev
lxc-start: start.c: lxc_spawn: 914 failed to create the network
lxc-start: start.c: __lxc_start: 1164 failed to spawn 'centos-test'
lxc-start: lxc_start.c: main: 344 The container failed to start.
lxc-start: lxc_start.c: main: 348 Additional information can be obtained by setting the --logfile and --logpriority options.

I was quite surprised that Fedora did not create the lxcbr0 bridge interface automatically. Instead, we will use the existing virbr0 provided by libvirtd.
$ sudo yum install libvirt-daemon
sudo systemctl start libvirtd

Check the bridge network interface.
$ brctl show
bridge name     bridge id               STP enabled     interfaces
virbr0          8000.525400c28250       yes             virbr0-nic

Edit our container config file and change the network link from lxcbr0 to virbr0.
$ sudo vim /var/lib/lxc/centos-test/config
lxc.network.link = virbr0

Try to start the container again, this time, another '819 Permission denied' error.
$ sudo lxc-start -F -n centos-test
lxc-start: conf.c: lxc_mount_auto_mounts: 819 Permission denied - error mounting /usr/lib64/lxc/rootfs/proc/sys/net on /usr/lib64/lxc/rootfs/proc/net flags 4096
lxc-start: conf.c: lxc_setup: 3833 failed to setup the automatic mounts for 'centos-test'
lxc-start: start.c: do_start: 699 failed to setup the container
lxc-start: sync.c: __sync_wait: 51 invalid sequence number 1. expected 2
lxc-start: start.c: __lxc_start: 1164 failed to spawn 'centos-test'
lxc-start: lxc_start.c: main: 344 The container failed to start.
lxc-start: lxc_start.c: main: 348 Additional information can be obtained by setting the --logfile and --logpriority options.

After struggled and googled for answer for the past hours, it actually dawned to me that the '819 Permission denied' error is related to SELinux policy. I did a quick check by disabled SELinux and reboot the machine and was able to start the container.

Also, just to confirm the SELinux error for lxc-start.
$ sudo grep lxc-start /var/log/audit/audit.log | tail -n 1
type=AVC msg=audit(1430849851.869:714): avc:  denied  { mounton } for  pid=3780 comm="lxc-start" path="/usr/lib64/lxc/rootfs/proc/1/net" dev="proc" ino=49148 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tclass=dir permissive=0

Start the SELinux Alert Browser and run the below commands to add the security policy.
$ sealert

$ sudo grep lxc-start /var/log/audit/audit.log | audit2allow -M mypol
******************** IMPORTANT ***********************
To make this policy package active, execute:

semodule -i mypol.pp

$ sudo semodule -i mypol.pp

Start our container again and check it status.
$ sudo lxc-start -n centos-test 
[[email protected] ~]$ sudo lxc-info -n centos-test
Name:           centos-test
State:          RUNNING
PID:            6742
CPU use:        0.44 seconds
BlkIO use:      18.55 MiB
Memory use:     12.14 MiB
KMem use:       0 bytes
Link:           veth4SHUE1
 TX bytes:      578 bytes
 RX bytes:      734 bytes
 Total bytes:   1.28 KiB

Attach to our container. There is no login needed.
$ sudo lxc-attach -n centos-test
[[email protected] /]# uname -a
Linux centos-test 4.0.1-300.fc22.x86_64 #1 SMP Wed Apr 29 15:48:25 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

[[email protected] /]# cat /etc/centos-release 
CentOS release 6.6 (Final)

On Using Fedora Rawhide (F22)

I've been using Fedora Rawhide (F22) for a while until my hard disc failed on me causing file system corruption that I can't seem to boot into the system. Here are some of my lesson learned when using bleeding edge release.

1. Dual-boot or triple-boot your system.
Install multiple Operating System (OS) in your system. Preferable different GNU/Linux distros. For example a stable Fedora F21 and Fedora Rawhide (F22). If you're dual-booting between Windows and GNU/Linux, make sure you pick the common file system such as ext2/3/4, there are quite a few software exists that can let you access your GNU/Linux partition like Ext2Fsd, Linux Reader, or Ext2Read. If you intend to use block device encryption as in Linux Unified Key Setup (LUKS), you can try DoxBox.

2. Ctrl-Alt-F1/F2/F3/F4/Fn
There are a few incidents after upgrading to the latest kernel, I can't login through the graphical user interface or X. Hence, you're stuck in the console. The best way is to wait for a few days (which is why you should dual-boot to use other distros or OS) for any updates or fixes. Boot up the system but login through different terminal using the keyboard short fo Crtl-Alt-Fn keys. Run the yum update through the console and you should be able to boot up. Or you can boot up using the last working kernel version, you can see that in GNU Grub bootloader, which is likely to work.

3. nmcli
The console tool to manage NetworkManager. Setting up Wifi in console used to be quite troublesome, but since the release of nmcli, we have far more easier tool to manage our wireless connection. This is so true when you've to switch to different terminal to update your distribution without using at LAN cable. See 2. Example of usages shown below.

Check available Wifi connections. Yes, that is a bar graph in the console. Awesome, right?
$ nmcli dev wifi list
*  SSID         MODE   CHAN  RATE       SIGNAL  BARS  SECURITY  
*  AAA          Infra  2     54 Mbit/s  74      ▂▄▆_  WPA1 WPA2 
   BBB          Infra  2     54 Mbit/s  20      ▂___  WPA1 WPA2 
   CCC          Infra  1     54 Mbit/s  35      ▂▄__  WPA2  

To make a Wifi connection. To prevent the Bash shell from saving your password in the history, prepend an extra space before the command.
  !----- extra space
  v
$  nmcli dev wifi connect AAA password 
Device 'wlp3s0' successfully activated with 'bx12345e-x2w3-112z-kk33-e348f22345qa'.

4. Recovery Disk
If you don't dual-boot with different GNU/Linux distros. Use a recovery Live CD or USB. Find the extra unused thumb drive and install in it. If you save you a lot of time especially when there is disaster like hard disc failure and you have to wait to download a full Live CD.

Conclusion. If you want to try the unstable GNU/Linux early release, be prepared for breakage and constant restarts. Do remember to backup daily. Or you can switch to a rolling-release distro like ArchLinux, where packages are continually updated instead of re-installation.

DNF Unofficially Replaced Yum In Fedora 22

As I was setting up my Fedora F22 (Rawhide) installation, I've noticed that the Yellowdog Updater, Modified (YUM), the default installer has been deprecated in favour of new Dandified Yum (DNF). As this email in the mailing list confirms my assumption before the release of Fedora 22 Beta in coming week. Example as shown below when I tried to install Google Chrome web browser.

Using the good old RPM Package Manager (RPM) where the installation failed due to failed dependencies.
$ sudo rpm -ivh google-chrome-stable_current_x86_64.rpm
[sudo] password for ang:
warning: google-chrome-stable_current_x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 7fac5991: NOKEY
error: Failed dependencies:
 lsb >= 4.0 is needed by google-chrome-stable-41.0.2272.118-1.x86_64
 libXss.so.1()(64bit) is needed by google-chrome-stable-41.0.2272.118-1.x86_64

Instead of searching for the package names of the dependencies, we can use the yum localinstall command to resolve that for us. Unfortunately, the yum command has been delegated to dnf where the localinstall command does not exists.
$ sudo yum localinstall google-chrome-stable_current_x86_64.rpm
Yum command has been deprecated, use dnf instead.
See 'man dnf' and 'man yum2dnf' for more information.
To transfer transaction metadata from yum to DNF, run 'dnf migrate'Redirecting to '/usr/bin/dnf localinstall google-chrome-stable_current_x86_64.rpm'

No such command: localinstall. Please use /usr/bin/dnf --help
It could be a DNF plugin command.

Hence, we use the dnf command directly. I'm still puzzle why we need 122 packages just to install Google Chrome. Most likely the dependencies of the LSB packages and all the Perl libraries.
$ sudo dnf install ./google-chrome-stable_current_x86_64.rpm

......
Transaction Summary
=================================================================================
Install  122 Packages

Total size: 66 M
Total download size: 21 M
Installed size: 245 M
Is this ok [y/N]:

I still prefer YUM over DNF due to my familiarity with YUM instead of DNF. However, both are still lacking behind the apt-get despite DNF trying its best to narrow the gap.

Creating Live USB Media for Fedora Rawhide (F22)

Since my hard disc failed on me a few days back, I've to reinstall my GNU/Linux environment again. Since I don't have any USB thumbdrive with me, is far more economical to perform the installation through CD. However, after comparing the price between empty CDs and a USB thumbdrive, is far more economical to use an thumbdrive. Furthermore, you can "burn" the different multiple ISO image to the same thumbdrive.

Instead of using the last stable Fedora release (F21), I opt for the Rawhide (F22) release. You can download the nightly image ISO. Note that this is a network installation image, hence the small image size of 500-plus MB.

The nightly image is quite buggy and installer may not work. If you stuck with the nightly image, consider trying the Alpha pre-release image instead.

To reduce the download time, we'll use Aria2, a console downloader program that support multiple parallel HTTP connections. On the safe side, we're using a maximum 4 connections per server (-x 4), the default is 1. You can use different value but your mileage may vary. Also, it's considered a poor etiquette to make too many connections.
$ aria2c -x 4 -o fedora_rawhide_f22.iso http://download.fedoraproject.org/pub/fedora/linux/development/rawhide/x86_64/os/images/boot.iso

Plug in your USB thumbdrive. Check the device name using the lsblk command to list the available block devices. This is currently my go-to command to see all available devices and partitions. As we can see below, the device name for USB thumbdrive is /dev/sdb.
$ lsblk
NAME           MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda              8:0    0 119.2G  0 disk  
├─sda1           8:1    0   499M  0 part  
├─sda2           8:2    0   300M  0 part  /boot/efi
├─sda3           8:3    0   128M  0 part  
├─sda4           8:4    0  96.3G  0 part  /
├─sda5           8:5    0  17.3G  0 part  
├─sda6           8:6    0     1G  0 part  
└─sda7           8:7    0   3.8G  0 part  
  └─cryptswap1 252:0    0   3.8G  0 crypt [SWAP]
sdb              8:16   1   7.5G  0 disk  
└─sdb1           8:17   1   7.5G  0 part

Let's burn the ISO image using the dd command. Roughly around 1 minute and 22 seconds.
$ time sudo dd if=fedora_22_boot.iso of=/dev/sdb bs=4M
138+1 records in
138+1 records out
579862528 bytes (580 MB) copied, 80.0856 s, 7.2 MB/s

real    1m20.113s
user    0m0.016s
sys     0m5.256s

To verify that we've burned the image successfully, we can test it using a virtual machine like QEMU (Quick Emulator) instead on the intended physical machine. Note that this is under Ubuntu 15.04 Vivid Vervet.
$ sudo apt-get install qemu
$ sudo qemu-system-x86_64 -hda /dev/sdb -m 1024 -vga std

If you can see result from below screenshot, then you've successfully burn the ISO to the USB thumbdrive.