Feb 28

Fedora (Let’s Make A Server!)



The first time that I installed Fedora onto a random machine was when Fedora Core 3 had just been released. I didn’t really know much about the system, but then again, I wasn’t really interested in learning it either. My true mission at that time was to create a TIVO machine that I could use to record TV shows. Back in those days, it was unheard of! We used VCRs for everything, but you could find the occasional mp4 recorder. It was a hassle, however, to hook up that recorder to the TV each time you wanted to record something. So I wanted a more efficient way to grab my shows off of my awesome 32 inch CRT! That’s when I decided to buy a Hauppauge cable card, an IR receiver, a new hard drive and a couple sticks of RAM to shove into what will become my Fedora powered TIVO box.

These days, the installations are MUCH easier, but they still require a small road map and the right commands. When I cancelled all of my godaddy.com accounts for their bad customer service, I went ahead and decided to create my own web and email server; so I installed Fedora again. We already had a wonderful relationship from back in the day, so why give up on it now.

This writing will show you some of the techniques that I use to set up a web server. Every admin has their own way of doing things, but I can tell you that this server has treated me very well and has been stable for a very long time. I hope yours is the same! Here we go…


  1. Create Sudo User
  2. Create SSH Key on Local Machine
  3. Add to User’s authorized_keys
  4. Configure Server Side SSH
  5. Configure iptables (Firewall)
  6. Yum Update
  7. VSFTP Install / Config (FTP Server)
  8. Apache Install (Web Server)
  9. SSH : Create Self-signed Certificate
  10. Enable SSH (https://)
  11. MySQL Install
  12. Postfix Install / config (Mail Server)
  13. Dovecot Install / Config (SMTP)

# Each time you see a comment (#) character, it means that whatever is put in front of it is simply informational. If you see the prompt ($) character, that means that I am entering commands into my terminal window. If you see nothing in front of a bunch of text, it simply means that the command gave me some output and I am displaying that for you.


# A brand new installation of Fedora will only have the root user installed. As a good technique, you never want to use the root user for everything. It’s very convenient at times, but the root user has permissions to do anything and everything with no confirmations… and those actions are final. Instead, you should create your own user (it’s more fun anyway) and give it sudo privileges so that it can act as root if needed. This is always the first thing that I do with a new installation.

# From my own unix terminal, I’ll remote into my new server. It goes without saying, if your new server installation is on a computer that’s sitting right in front of you, skip this step. If you absolutely want to do it, try: $ ssh [email protected] 🙂

$ssh [email protected]<server ip address>
[email protected]<server ip address>’s password:

$ passwd
Changing password for user root.
New password:
Retype new password:
passed: all authentication tokens updated successfully

$ adduser servertheories

$ passwd servertheories
Changing password for user servertheories
New password:
Retype new password:
passed: all authentication tokens updated successfully.

$ visudo
# run visudo as root
# add this to the bottom: servertheories ALL=(ALL) ALL

$ su servertheories

$ sudo ls -al
total 28
dr-xr-x—. 2 root root 4096 Jun 13 2012 .
drwxr-xr-x. 18 root root 4096 Jan 16 01:08 ..
-rw-r–r–. 1 root root 18 Jan 14 2012 .bash_logout
-rw-r–r–. 1 root root 176 Jan 14 2012 .bash_profile
-rw-r–r–. 1 root root 176 Jan 14 2012 .bashrc
-rw-r–r–. 1 root root 100 Jan 14 2012 .cshrc
-rw-r–r–. 1 root root 129 Jan 14 2012 .tcshrc
# we’re just checking to make sure that everything worked
# if a list was shown, then sudo privs were granted to servertheories

$ cd ~
# this gets us to servertheories’s home directory (/home/servertheories)


# Using the Terminal on my Mac, I used the command

$ ssh-keygen -t rsa

$ scp ~/.ssh/id_rsa.pub [email protected]:/home/servertheories/
# You will need to replace the bogus IP address with your server’s IP address.
# Secure copy is a pretty convenient way to transfer files via command line, you can use it to to transfer to or from the server:  command –> options (usually -r) –> where from –> where to …or: command –> options –> where to –> where from


# We are back to an SSH session with the server

$ cd ~

$ mkdir .ssh

$ mv id_rsa.pub /home/servertheories/.ssh/authorized_keys
# authorized_keys let’s the server and client talk securely. You just installed a public key onto the server that talks to the private key on your home/client computer to create a secure session (no password auth needed)

$ cd .ssh

$ ls
# just making sure it all went as planned

$ chown -R servertheories:servertheories ~/.ssh
# changing the ownership is only needed if you created the file as root.
# If the ownership was already servertheories, then leave it be

$ chmod 700 ~/.ssh

$ chmod 600 ~/.ssh/authorized_keys

# Your computer is now ready to talk to this server using the keys that you just installed.  When you connect via SSH, it should not prompt you for a password.  Instead, it will simply tell you the las time you logged on and give you a prompt.


# We want to do a few things to make our server more secure.  The following process will configure the SSH (which you may be using now) to work on a different port than normal and not allow requests for root to log on.  Since you will not be logging on as root, you can assume that any attempt to do so will not be done by you… thus preventing hacking attempts.

$ cd /etc/ssh

$ sudo nano sshd_config
# (use ctl-o to save and ctl-x to exit)

# Change or add the following not including the comment (#) character:
# Port 22 –> change to a number that only you know (uncommon port number)
# Protocol 2
# PermitRootLogin no
# PasswordAuthentication no
# UseDNS no
# AllowUsers servertheories

# If you changed the port number, you will need to add a firewall exemption:
# sudo iptables -I INPUT -m tcp -p tcp –dport (Port here!) -j ACCEPT


# Depending on the type of server, you’ll need certain exemptions added to your iptables. Here are some common ones:

NOTE: if you copy/paste, the – – dport may turn into –dport.  two ‘dashes’ are required.

$ sudo iptables -I INPUT -m tcp -p tcp –dport http -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport https -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport ssh -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport ftp -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport ftp-data -j ACCEPT
$ sudo iptables -I INPUT -m tcp -p tcp –dport mysql -j ACCEPT

# Now list them to make sure they took

$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp — anywhere anywhere tcp dpt:mysql
ACCEPT tcp — anywhere anywhere tcp dpt:ftp-data
ACCEPT tcp — anywhere anywhere tcp dpt:ftp
ACCEPT tcp — anywhere anywhere tcp dpt:ssh
ACCEPT tcp — anywhere anywhere tcp dpt:https
ACCEPT tcp — anywhere anywhere tcp dpt:http
ACCEPT all — anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp — anywhere anywhere
ACCEPT all — anywhere anywhere
ACCEPT tcp — anywhere anywhere state NEW tcp dpt:ssh
REJECT all — anywhere anywhere reject-with icmp-host-prohibited
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT all — anywhere anywhere reject-with icmp-host-prohibited
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
# If the tables look good, you’ll need to save them

$ /usr/libexec/iptables.init save

$ sudo service iptables restart
# I will usually restart the iptables service to make sure the save worked

$ sudo iptables -L
# The list should look exactly the same as before you restarted (iptables -L)
# You can also use: /bin/systemctl restart iptables.service, but my way has fewer letters to type 🙂


# Yum is a command used to receive installs and updates for programs
# We want to update all of our software before making this a server box

$ sudo yum update
Loaded plugins: fastestmirror, presto
Determining fastest mirrors
fedora/metalink | 19 kB 00:00
updates/metalink | 15 kB 00:00
* fedora: fedora.mirror.lstn.net
* updates: fedora.mirror.lstn.net
Transaction Summary
Install 1 Package (+4 Dependent packages)
Upgrade 145 Packages
Total download size: 143 M
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
updates/prestodelta | 1.4 MB 00:00
Processing delta metadata
Download delta size: 57 M

# Depending on your box, this could take a while… just let it happen.


# For this install, we’ll get the machine prepared for a WordPress installation
# WordPress uses vsftpd to install plugins, themes, etc… well, at least it will with the right configurations…
# Credit goes to Brian

$ sudo yum install vsftpd

$ sudo service vsftpd stop

$ cd /etc/vsftpd

$ sudo nano vsftpd.conf
# (use ctl-o to save and ctl-x to exit)

# Change or add the following without the comment (#) character:
# listen=YES
# anonymous_enable=NO
# local_enable=YES
# write_enable=YES
# local_umask=022
# dirmessage_enable=YES
# use_localtime=YES
# xferlog_enable=YES
# secure_chroot_dir=/var/run/vsftpd/empty
# pam_service_name=vsftpd
# rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
# rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
# ssl_enable=YES
# allow_anon_ssl=NO
# force_local_data_ssl=YES
# force_local_logins_ssl=YES
# ssl_tlsv1=YES
# ssl_sslv2=NO
# ssl_sslv3=NO
# anon_world_readable_only=NO
# anon_upload_enable=NO
# anon_mkdir_write_enable=NO
# connect_from_port_20=NO
# listen_port=2112

$ sudo service vsftpd restart

$ sudo service vsftpd enable
# Enable tells the server that you would like it to start this service every time you boot into linux.

# You’ve configured the firewall, as well as vsftpd.  Try to connect via an FTP client and see what happens.   Remember, with this configuration, you changed the FTP port to 2112, so use that when trying to connect.


$ sudo yum install httpd mod_ssl php php-common php-gd php-mcrypt php-pear php-pecl-memcache php-mhash php-mysql php-xml
# You can google each of these software installs, but these are the most common installs for the apache web server.

$ sudo service https start
# this starts up the web server
# configurations are all default at this point
# In your browser, visit https://<insert server ip address>
# You should see the apache test splash page

$ sudo service httpd enable

# As you can see, there’s not much to the web server install.  On the Fedora machine, Apache runs under the alias of “httpd” which is a daemon that serves out the web pages to those who request them.  Therefore, when using, accessing or restarting Apache, you will use the httpd reference.

# In order for your web page to show up, you will need to move it to /var/www/http/ which is what’s called the DocumentRoot, or the place where your web server looks when a page is requested.


This writing will show how to install a self-signed key to use as the authentication for https:// sites. The disadvantage to a self-signed key is that you will receive an error in the web browser when you visit https://www.<your new site>.com. The browser will always give you the option to continue, however it somewhat dis-credits your site for public eyes. Therefore, if you’re up to it, I suggest buying a verified certificate from a reputable site. The cheapest one that I’ve found is a $50 cert from Rapidssl.com. They will do a verification via a phone call and an email, so have your phone handy. You’ll have to enter some numbers into the keypad that are displayed after you purchase the certificate. It’s extremely easy and very quick… unless you’re like me and do it from Italy where I don’t have a local US phone number. I made it work though 🙂

Additionally, you will be asked to enter a passphrase while creating your server.key file. This is optional. Here are my thoughts. If you are going to self-sign a certificate, don’t worry about the pass phrase at all… httpd will ask for it each time it starts, and although that is configurable, it yields no advantages for a self-signed cert. HOWEVER, if you are going to purchase a legitimate certificate, absolutely have a passphrase associated with it. That purchased certificate is what tells the world that you are who you claim to be. If anyone gets their hands on that cert, they can claim to be you….. but only if they can start the httpd service. The pass phrase is just one more layer of protection for you.

$ sudo make server.key
umask 77 ; \
/usr/bin/openssl genrsa -aes128 2048 > server.key
Generating RSA private key, 2048 bit long modulus
e is 65537 (0x10001)
Enter pass phrase:
Verifying – Enter pass phrase:

$ sudo openssl rsa -in server.key -out server.key
# To get rid of the pass phrase, use this command
# The resulting file is your private key file without a passphrase

$ make server.csr
umask 77 ; \
/usr/bin/openssl req -utf8 -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:City
Locality Name (eg, city) [Default City]:City
Organization Name (eg, company) [Default Company Ltd]:Server Use For Testing
Organizational Unit Name (eg, section) []:Server Use For Testing
Common Name (eg, your name or your server’s hostname) []:testserver
Email Address []:[email protected]
Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

# Don’t worry about the challenge password or the optional company name. Leave them blank and hit enter. You need to put something in the other fields, but again, if this is a self-signed certificate, just stick to the basics for answers.

$ sudo openssl x509 -in server.csr -out server.crt -req -signkey server.key -days 3650

$ sudo mv server.* /etc/pki/tls/certs
# You will need the certifications in this location, however, another technique is to create a public and a private folder within the /etc/pki/tls/certs folder. This way, the private key is separated from the public key giving you some additional security.

$ sudo chmod 400 server.*

$ ls -al
-r——–. 1 root root 1395 Jan 17 05:02 server.crt
-r——–. 1 root root 1167 Jan 17 05:00 server.csr
-r——–. 1 root root 1679 Jan 17 04:58 server.key

– ENABLE SSH (https://) –

Enabling an https website is extremely important if you are going to use sensitive information on that website.  For instance, if you are going to password protect a website, the username and password will be sent in plain text unless you enable your website for https.  This process will use the new server.key file you created to enable the secure connection (https) for your website.

$ cd /etc/httpd/conf.d/

$ sudo nano ssl.conf
# (use ctl-o to save and ctl-x to exit)

# Change or add the following without the comment (#) character:
# DocumentRoot “/var/www/html”
# ServerName www.<your new site>.com:443
# SSLCertificateFile /etc/pki/tls/certs/server.crt
# SSLCertificateKeyFile /etc/pki/tls/certs/server.key

The DocumentRoot setting will tell browsers where to go. The ServerName setting will tell your apache server to serve this DocumentRoot when a request for www.<your new site>.com comes through, but in this case, only if it is with port number 443. If the same request came through the default and unsecured port number 80, apache would serve the request through the httpd.conf file instead of the ssl.conf. The SSLCertificcateFile gives apache the location of that certificate that you just created… both the public certificate file (.crt) and the private key file (.key).

$ sudo service httpd restart

# To see how to configure httpd to start with automatic passphrase entry, checkout this post.


# One of the quickest and easiest ways to get your web page up and running is to install WordPress on your server.  For WordPress to work, however, MySQL will need to be running in the background.  This will show you how to install MySQL on your server.

# There is a technique for web servers to link to a remote server for their MySQL needs. This is a great technique if you have the resources. You can do this same install on a separate server and change the hostname to an fsdn address (the server dot the domain dot com / mysql.servertheories.com) and create DNS entries to point that fsdn address to your remote server.

# This is probably the easiest install of them all

$ sudo yum install mysql-server

$ sudo service mysqld start

$ sudo mysql_secure_installation
# Answer yes to all of the questions and remember your password!

$ sudo service mysqld start

$ sudo service mysql enable

# Log onto MySQL for the first time and make sure it works.

$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.5.29 MySQL Community Server (GPL)
mysql> quit


# Content Management Systems, or CMS’s are a great way to get your information out there for your customers to see. There are quite a few of them available free of charge, but my favorite has always been WordPress. It’s simple, and best of all, my customers aren’t afraid of the interface due to that simplicity. If you want to get very technical, you can program your own code into what’s called a ‘child theme’ or you can just do everything from the default installation. A second choice is Drupal. I did my first install only this week and am very excited to learn more about it. I don’t want to form anyone’s opinions, but I have heard some bad reviews regarding Drupal. A very credible programmer friend of mine told me that his team had been sending suggestions for broken code in Drupal for a long time, and the current iteration still has those same bits of code. From his perspective, he might be right. But I intend to test the Drupal install from my customer’s perspective. Stay tuned for write-ups as I experiment with various things. Other CMS’s will not be covered in this writing, but it’s worth googling CMS to find out what’s out there and which one fits your needs best.

# For the famous 5-minute WordPress install instructions, click here.

# For my first Drupal install (ever), click here.


# If you’re interested in going further than just a web and MySQL server, try creating a mail and SMTP server.  The basic instals are here, but I’ll save the configurations for a new day.  If you feel like continuing with the installs, just keep the basic theories that you learned today in mind while configuring your new mail server.

# Postfix and Dovecot are great programs that are fairly easy to configure.  However, you can go down the wrong path pretty quickly with an incorrect configuration.  So do one thing at a time and remember your troubleshooting techniques.  Log files are your friend!

#  The following command will get you started with the mail and SMTP server.  Have fun!

$ sudo yum install postfix postfix-mysql postfix-tls libsasl2-2 libsasl2-modules libsasl2-modules-sql sasl2-bin libpam-mysql openssl telnet mailx dovecot


If anything didn’t work, don’t be afraid to scrap and start over.  It sounds harsh, but sometimes that’s the best way to learn.  If you don’t feel like scrapping the project, check out your log files, figure out what went wrong, and try it again.  The beautiful thing that I’ve discovered about UNIX is anything that happens has a reason.  More than likely, it’s a simple number or letter somewhere that you typed in wrong.  Find that, and you’ve found your problem.


Always remember… WHAT IF AND WHY NOT?!?